Fix field access from inline asm. See tests/mini/asm10.d

This commit is contained in:
Frits van Bommel
2009-03-12 23:48:43 +01:00
parent ed9af11856
commit 8b185b8b6a
3 changed files with 79 additions and 30 deletions

View File

@@ -1450,6 +1450,7 @@ namespace AsmParserx8632
{
AsmCode * asmcode = new AsmCode ( N_Regs );
asmcode->insnTemplate = insnTemplate.str();
Logger::cout() << "insnTemplate = " << asmcode->insnTemplate << '\n';
stmt->asmcode = ( code* ) asmcode;
}
@@ -2048,22 +2049,35 @@ namespace AsmParserx8632
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 @@ namespace AsmParserx8632
}
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 @@ namespace AsmParserx8632
}
asmcode->insnTemplate = insnTemplate.str();
Logger::cout() << "insnTemplate = " << asmcode->insnTemplate << '\n';
return true;
}

View File

@@ -1572,6 +1572,7 @@ namespace AsmParserx8664
{
AsmCode * asmcode = new AsmCode ( N_Regs );
asmcode->insnTemplate = insnTemplate.str();
Logger::cout() << "insnTemplate = " << asmcode->insnTemplate << '\n';
stmt->asmcode = ( code* ) asmcode;
}
@@ -2170,22 +2171,35 @@ namespace AsmParserx8664
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 @@ namespace AsmParserx8664
}
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 @@ namespace AsmParserx8664
}
asmcode->insnTemplate = insnTemplate.str();
Logger::cout() << "insnTemplate = " << asmcode->insnTemplate << '\n';
return true;
}

31
tests/mini/asm10.d Normal file
View File

@@ -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);
}