changeset 1109:97d80437cb80

Fix field access from inline asm. See tests/mini/asm10.d
author Frits van Bommel <fvbommel wxs.nl>
date Thu, 12 Mar 2009 23:48:43 +0100
parents d03814546977
children fd631764eaac
files gen/asm-x86-32.h gen/asm-x86-64.h tests/mini/asm10.d
diffstat 3 files changed, 79 insertions(+), 30 deletions(-) [+]
line wrap: on
line diff
--- 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;
         }
 
--- 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;
         }
 
--- /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);
+}