# HG changeset patch # User Frits van Bommel # Date 1236898123 -3600 # Node ID 97d80437cb8031ec6839c47d7bce7222f3a4405a # Parent d038145469779c3621368e4a6f372a0a35402e3a Fix field access from inline asm. See tests/mini/asm10.d diff -r d03814546977 -r 97d80437cb80 gen/asm-x86-32.h --- a/gen/asm-x86-32.h Thu Mar 12 23:31:26 2009 +0100 +++ b/gen/asm-x86-32.h Thu Mar 12 23:48:43 2009 +0100 @@ -1450,6 +1450,7 @@ { AsmCode * asmcode = new AsmCode ( N_Regs ); asmcode->insnTemplate = insnTemplate.str(); + Logger::cout() << "insnTemplate = " << asmcode->insnTemplate << '\n'; stmt->asmcode = ( code* ) asmcode; } @@ -2048,22 +2049,35 @@ use_star = opTakesLabel();//opInfo->takesLabel(); - if ( operand->segmentPrefix != Reg_Invalid || operand->constDisplacement ) - { - if ( operand->symbolDisplacement.dim ) - { - insnTemplate << operand->constDisplacement << '+'; + if (Logger::enabled()) { + Logger::cout() << "Opr_Mem\n"; + LOG_SCOPE + Logger::cout() << "baseReg: " << operand->baseReg << '\n'; + Logger::cout() << "segmentPrefix: " << operand->segmentPrefix << '\n'; + Logger::cout() << "constDisplacement: " << operand->constDisplacement << '\n'; + for (int i = 0; i < operand->symbolDisplacement.dim; i++) { + Expression* expr = (Expression*) operand->symbolDisplacement.data[i]; + Logger::cout() << "symbolDisplacement[" << i << "] = " << expr->toChars() << '\n'; } - //addOperand(fmt, Arg_Integer, newIntExp(operand->constDisplacement), asmcode); - if ( opInfo->operands[i] & Opr_Dest ) - asmcode->clobbersMemory = 1; } - if ( operand->segmentPrefix != Reg_Invalid ) { writeReg ( operand->segmentPrefix ); insnTemplate << ':'; } + if ( (operand->segmentPrefix != Reg_Invalid && operand->symbolDisplacement.dim == 0) + || operand->constDisplacement ) + { + insnTemplate << operand->constDisplacement; + if ( operand->symbolDisplacement.dim ) + { + insnTemplate << '+'; + } + operand->constDisplacement = 0; + //addOperand(fmt, Arg_Integer, newIntExp(operand->constDisplacement), asmcode); + if ( opInfo->operands[i] & Opr_Dest ) + asmcode->clobbersMemory = 1; + } if ( operand->symbolDisplacement.dim ) { Expression * e = ( Expression * ) operand->symbolDisplacement.data[0]; @@ -2178,12 +2192,6 @@ } if ( use_star ) insnTemplate << '*'; - if ( operand->segmentPrefix != Reg_Invalid && !(operand->constDisplacement) ) - { - insnTemplate << operand->constDisplacement; - if ( opInfo->operands[i] & Opr_Dest ) - asmcode->clobbersMemory = 1; - } if ( operand->baseReg != Reg_Invalid || operand->indexReg != Reg_Invalid ) { insnTemplate << '('; @@ -2209,6 +2217,7 @@ } asmcode->insnTemplate = insnTemplate.str(); + Logger::cout() << "insnTemplate = " << asmcode->insnTemplate << '\n'; return true; } diff -r d03814546977 -r 97d80437cb80 gen/asm-x86-64.h --- a/gen/asm-x86-64.h Thu Mar 12 23:31:26 2009 +0100 +++ b/gen/asm-x86-64.h Thu Mar 12 23:48:43 2009 +0100 @@ -1572,6 +1572,7 @@ { AsmCode * asmcode = new AsmCode ( N_Regs ); asmcode->insnTemplate = insnTemplate.str(); + Logger::cout() << "insnTemplate = " << asmcode->insnTemplate << '\n'; stmt->asmcode = ( code* ) asmcode; } @@ -2170,22 +2171,35 @@ use_star = opTakesLabel();//opInfo->takesLabel(); - if ( operand->segmentPrefix != Reg_Invalid || operand->constDisplacement ) - { - if ( operand->symbolDisplacement.dim ) - { - insnTemplate << operand->constDisplacement << '+'; + if (Logger::enabled()) { + Logger::cout() << "Opr_Mem\n"; + LOG_SCOPE + Logger::cout() << "baseReg: " << operand->baseReg << '\n'; + Logger::cout() << "segmentPrefix: " << operand->segmentPrefix << '\n'; + Logger::cout() << "constDisplacement: " << operand->constDisplacement << '\n'; + for (int i = 0; i < operand->symbolDisplacement.dim; i++) { + Expression* expr = (Expression*) operand->symbolDisplacement.data[i]; + Logger::cout() << "symbolDisplacement[" << i << "] = " << expr->toChars() << '\n'; } - //addOperand(fmt, Arg_Integer, newIntExp(operand->constDisplacement), asmcode); - if ( opInfo->operands[i] & Opr_Dest ) - asmcode->clobbersMemory = 1; } - if ( operand->segmentPrefix != Reg_Invalid ) { writeReg ( operand->segmentPrefix ); insnTemplate << ':'; } + if ( (operand->segmentPrefix != Reg_Invalid && operand->symbolDisplacement.dim == 0) + || operand->constDisplacement ) + { + insnTemplate << operand->constDisplacement; + if ( operand->symbolDisplacement.dim ) + { + insnTemplate << '+'; + } + operand->constDisplacement = 0; + //addOperand(fmt, Arg_Integer, newIntExp(operand->constDisplacement), asmcode); + if ( opInfo->operands[i] & Opr_Dest ) + asmcode->clobbersMemory = 1; + } if ( operand->symbolDisplacement.dim ) { Expression * e = ( Expression * ) operand->symbolDisplacement.data[0]; @@ -2300,12 +2314,6 @@ } if ( use_star ) insnTemplate << '*'; - if ( operand->segmentPrefix != Reg_Invalid && !(operand->constDisplacement)) - { - insnTemplate << operand->constDisplacement; - if ( opInfo->operands[i] & Opr_Dest ) - asmcode->clobbersMemory = 1; - } if ( operand->baseReg != Reg_Invalid || operand->indexReg != Reg_Invalid ) { insnTemplate << '('; @@ -2331,6 +2339,7 @@ } asmcode->insnTemplate = insnTemplate.str(); + Logger::cout() << "insnTemplate = " << asmcode->insnTemplate << '\n'; return true; } diff -r d03814546977 -r 97d80437cb80 tests/mini/asm10.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/mini/asm10.d Thu Mar 12 23:48:43 2009 +0100 @@ -0,0 +1,31 @@ +module asm10; + +struct S { + ushort first; + ushort second; + int unaccessed; +} + +void main() { + auto s = S(512, 42, -1); + ushort x = 0; + version(D_InlineAsm_X86) { + asm { + lea EAX, s; + mov CX, S.second[EAX]; + mov x, CX; + mov S.first[EAX], 640; + } + } else version(D_InlineAsm_X86_64) { + asm { + lea RAX, s; + mov CX, S.second[RAX]; + mov x, CX; + mov S.first[RAX], 640; + } + } + assert(x == 42); + assert(s.first == 640); + assert(s.second == 42); + assert(s.unaccessed == -1); +}