mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-02-13 02:13:14 +01:00
Use stringstream in asm generation instead of OutBuffer.
Besides looking better, this should reduce allocations and copying.
This commit is contained in:
101
gen/asm-x86-32.h
101
gen/asm-x86-32.h
@@ -1206,7 +1206,7 @@ namespace AsmParserx8632
|
||||
Scope * sc;
|
||||
|
||||
Token * token;
|
||||
OutBuffer * insnTemplate;
|
||||
std::ostringstream insnTemplate;
|
||||
|
||||
AsmOp op;
|
||||
AsmOpInfo * opInfo;
|
||||
@@ -1219,7 +1219,6 @@ namespace AsmParserx8632
|
||||
this->sc = sc;
|
||||
this->stmt = stmt;
|
||||
token = stmt->tokens;
|
||||
insnTemplate = new OutBuffer;
|
||||
|
||||
opInfo = NULL;
|
||||
|
||||
@@ -1450,8 +1449,7 @@ namespace AsmParserx8632
|
||||
void setAsmCode()
|
||||
{
|
||||
AsmCode * asmcode = new AsmCode ( N_Regs );
|
||||
asmcode->insnTemplateLen = insnTemplate->offset;
|
||||
asmcode->insnTemplate = ( char* ) insnTemplate->extractData();
|
||||
asmcode->insnTemplate = insnTemplate.str();
|
||||
stmt->asmcode = ( code* ) asmcode;
|
||||
}
|
||||
|
||||
@@ -1513,9 +1511,9 @@ namespace AsmParserx8632
|
||||
{
|
||||
case Arg_Integer:
|
||||
if ( e->type->isunsigned() )
|
||||
insnTemplate->printf ( "$%llu", e->toUInteger() );
|
||||
insnTemplate << "$" << e->toUInteger();
|
||||
else
|
||||
insnTemplate->printf ( "$%lld", e->toInteger() );
|
||||
insnTemplate << "$" << e->toInteger();
|
||||
break;
|
||||
|
||||
case Arg_Pointer:
|
||||
@@ -1536,10 +1534,10 @@ namespace AsmParserx8632
|
||||
|
||||
// osx needs an extra underscore
|
||||
if ( global.params.os == OSMacOSX )
|
||||
insnTemplate->writestring ( "_" );
|
||||
insnTemplate << "_";
|
||||
|
||||
// print out the mangle
|
||||
insnTemplate->writestring ( vd->mangle() );
|
||||
insnTemplate << vd->mangle();
|
||||
vd->nakedUse = true;
|
||||
break;
|
||||
}
|
||||
@@ -1554,25 +1552,23 @@ namespace AsmParserx8632
|
||||
}
|
||||
else
|
||||
{
|
||||
insnTemplate->writestring ( ( char* ) fmt );
|
||||
insnTemplate->printf ( "<<%s%d>>", ( mode==Mode_Input ) ?"in":"out", asmcode->args.size() );
|
||||
insnTemplate << fmt
|
||||
<< "<<" << (mode==Mode_Input ? "in" : "out") << asmcode->args.size() << ">>";
|
||||
asmcode->args.push_back ( AsmArg ( type, e, mode ) );
|
||||
}
|
||||
}
|
||||
void addOperand2 ( const char * fmtpre, const char * fmtpost, AsmArgType type, Expression * e, AsmCode * asmcode, AsmArgMode mode = Mode_Input )
|
||||
{
|
||||
assert ( !sc->func->naked );
|
||||
insnTemplate->writestring ( ( char* ) fmtpre );
|
||||
insnTemplate->printf ( "<<%s%d>>", ( mode==Mode_Input ) ?"in":"out", asmcode->args.size() );
|
||||
insnTemplate->writestring ( ( char* ) fmtpost );
|
||||
insnTemplate << fmtpre
|
||||
<< "<<" << (mode==Mode_Input ? "in" : "out") << ">>"
|
||||
<< fmtpost;
|
||||
asmcode->args.push_back ( AsmArg ( type, e, mode ) );
|
||||
}
|
||||
|
||||
void addLabel ( char* id )
|
||||
{
|
||||
insnTemplate->writestring ( sc->func->mangle() );
|
||||
insnTemplate->writestring ( "_" );
|
||||
insnTemplate->writestring ( id );
|
||||
insnTemplate << sc->func->mangle() << "_" << id;
|
||||
}
|
||||
|
||||
/* Determines whether the operand is a register, memory reference
|
||||
@@ -1653,8 +1649,7 @@ namespace AsmParserx8632
|
||||
|
||||
void writeReg ( Reg reg )
|
||||
{
|
||||
insnTemplate->writestring ( ( char* ) "%" );
|
||||
insnTemplate->write ( regInfo[reg].gccName.c_str(), regInfo[reg].gccName.length() );
|
||||
insnTemplate << "%" << regInfo[reg].gccName;
|
||||
}
|
||||
|
||||
bool opTakesLabel()
|
||||
@@ -1726,7 +1721,7 @@ namespace AsmParserx8632
|
||||
bool use_star;
|
||||
AsmArgMode mode;
|
||||
|
||||
insnTemplate = new OutBuffer;
|
||||
insnTemplate.str("");
|
||||
// %% todo: special case for something..
|
||||
if ( opInfo->linkType == Out_Mnemonic )
|
||||
mnemonic = alternateMnemonics[opInfo->link];
|
||||
@@ -1795,7 +1790,7 @@ namespace AsmParserx8632
|
||||
else if ( op == Op_Branch )
|
||||
{
|
||||
if ( operands[0].dataSize == Far_Ptr ) // %% type=Far_Ptr not set by Seg:Ofss OTOH, we don't support that..
|
||||
insnTemplate->writebyte ( 'l' );
|
||||
insnTemplate << 'l';
|
||||
}
|
||||
else if ( op == Op_fxch || op == Op_FfdRR_P || op == Op_FidR_P )
|
||||
{
|
||||
@@ -1837,11 +1832,10 @@ namespace AsmParserx8632
|
||||
{
|
||||
int mlen = strlen ( mnemonic );
|
||||
if ( mnemonic[mlen-1] == 'd' )
|
||||
insnTemplate->write ( mnemonic, mlen-1 );
|
||||
insnTemplate.write(mnemonic, mlen-1);
|
||||
else
|
||||
{
|
||||
insnTemplate->writestring ( ( char* ) mnemonic );
|
||||
insnTemplate->writebyte ( 'w' );
|
||||
insnTemplate << mnemonic << 'w';
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1856,12 +1850,11 @@ namespace AsmParserx8632
|
||||
int mlen = strlen ( mnemonic );
|
||||
if ( mnemonic[mlen-1] == 'd' )
|
||||
{
|
||||
insnTemplate->write ( mnemonic, mlen-1 );
|
||||
insnTemplate->writebyte ( 'l' );
|
||||
insnTemplate.write(mnemonic, mlen-1) << 'l';
|
||||
}
|
||||
else
|
||||
{
|
||||
insnTemplate->writestring ( ( char* ) mnemonic );
|
||||
insnTemplate << mnemonic;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1888,15 +1881,13 @@ namespace AsmParserx8632
|
||||
return false;
|
||||
}
|
||||
assert ( type_char != 0 );
|
||||
insnTemplate->write ( mnemonic, mlen-1 );
|
||||
insnTemplate->writebyte ( tc_1 );
|
||||
insnTemplate->writebyte ( type_char );
|
||||
insnTemplate.write(mnemonic, mlen-1) << tc_1 << type_char;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
insnTemplate->writestring ( ( char* ) mnemonic );
|
||||
insnTemplate << mnemonic;
|
||||
if ( type_char )
|
||||
insnTemplate->writebyte ( type_char );
|
||||
insnTemplate << type_char;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1950,12 +1941,12 @@ namespace AsmParserx8632
|
||||
asmcode->regs[Reg_EDX] = true;
|
||||
}
|
||||
|
||||
insnTemplate->writebyte ( ' ' );
|
||||
insnTemplate << ' ';
|
||||
for ( int i__ = 0; i__ < nOperands; i__++ )
|
||||
{
|
||||
int i;
|
||||
if ( i__ != 0 )
|
||||
insnTemplate->writestring ( ( char* ) ", " );
|
||||
insnTemplate << ", ";
|
||||
|
||||
fmt = "$";
|
||||
|
||||
@@ -2003,7 +1994,7 @@ namespace AsmParserx8632
|
||||
addOperand ( "$", Arg_LocalSize,
|
||||
( Expression * ) operand->symbolDisplacement.data[0], asmcode );
|
||||
if ( operand->constDisplacement )
|
||||
insnTemplate->writebyte ( '+' );
|
||||
insnTemplate << '+';
|
||||
else
|
||||
break;
|
||||
}
|
||||
@@ -2016,7 +2007,7 @@ namespace AsmParserx8632
|
||||
asmcode );
|
||||
|
||||
if ( operand->constDisplacement )
|
||||
insnTemplate->writebyte ( '+' );
|
||||
insnTemplate << '+';
|
||||
else
|
||||
// skip the addOperand(fmt, Arg_Integer...) below
|
||||
break;
|
||||
@@ -2033,11 +2024,11 @@ namespace AsmParserx8632
|
||||
}
|
||||
}
|
||||
if ( opTakesLabel() /*opInfo->takesLabel()*/ )
|
||||
insnTemplate->writebyte ( '*' );
|
||||
insnTemplate << '*';
|
||||
writeReg ( operand->reg );
|
||||
/*
|
||||
insnTemplate->writestring("%");
|
||||
insnTemplate->writestring(regInfo[operand->reg].name);
|
||||
insnTemplate << "%";
|
||||
insnTemplate << regInfo[operand->reg].name;
|
||||
*/
|
||||
break;
|
||||
case Opr_Mem:
|
||||
@@ -2061,8 +2052,7 @@ namespace AsmParserx8632
|
||||
{
|
||||
if ( operand->symbolDisplacement.dim )
|
||||
{
|
||||
insnTemplate->printf ( "%d", operand->constDisplacement );
|
||||
insnTemplate->writebyte ( '+' );
|
||||
insnTemplate << operand->constDisplacement << '+';
|
||||
}
|
||||
//addOperand(fmt, Arg_Integer, newIntExp(operand->constDisplacement), asmcode);
|
||||
if ( opInfo->operands[i] & Opr_Dest )
|
||||
@@ -2072,7 +2062,7 @@ namespace AsmParserx8632
|
||||
if ( operand->segmentPrefix != Reg_Invalid )
|
||||
{
|
||||
writeReg ( operand->segmentPrefix );
|
||||
insnTemplate->writebyte ( ':' );
|
||||
insnTemplate << ':';
|
||||
}
|
||||
if ( operand->symbolDisplacement.dim )
|
||||
{
|
||||
@@ -2163,15 +2153,15 @@ namespace AsmParserx8632
|
||||
// simply write out the mangle
|
||||
// on osx, prepend extra _
|
||||
if ( global.params.os == OSMacOSX )
|
||||
insnTemplate->writestring ( "_" );
|
||||
insnTemplate->writestring ( decl->mangle() );
|
||||
insnTemplate << "_";
|
||||
insnTemplate << decl->mangle();
|
||||
// addOperand2("${", ":c}", Arg_Pointer, e, asmcode);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( use_star )
|
||||
{
|
||||
insnTemplate->writebyte ( '*' );
|
||||
insnTemplate << '*';
|
||||
use_star = false;
|
||||
}
|
||||
|
||||
@@ -2187,28 +2177,28 @@ namespace AsmParserx8632
|
||||
}
|
||||
}
|
||||
if ( use_star )
|
||||
insnTemplate->writebyte ( '*' );
|
||||
insnTemplate << '*';
|
||||
if ( operand->segmentPrefix != Reg_Invalid && !(operand->constDisplacement) )
|
||||
{
|
||||
insnTemplate->printf ( "%d", operand->constDisplacement );
|
||||
insnTemplate << operand->constDisplacement;
|
||||
if ( opInfo->operands[i] & Opr_Dest )
|
||||
asmcode->clobbersMemory = 1;
|
||||
}
|
||||
if ( operand->baseReg != Reg_Invalid || operand->indexReg != Reg_Invalid )
|
||||
{
|
||||
insnTemplate->writebyte ( '(' );
|
||||
insnTemplate << '(';
|
||||
if ( operand->baseReg != Reg_Invalid )
|
||||
writeReg ( operand->baseReg );
|
||||
if ( operand->indexReg != Reg_Invalid )
|
||||
{
|
||||
insnTemplate->writebyte ( ',' );
|
||||
insnTemplate << ',';
|
||||
writeReg ( operand->indexReg );
|
||||
if ( operand->scale )
|
||||
{
|
||||
insnTemplate->printf ( ",%d", operand->scale );
|
||||
insnTemplate << "," << operand->scale;
|
||||
}
|
||||
}
|
||||
insnTemplate->writebyte ( ')' );
|
||||
insnTemplate << ')';
|
||||
if ( opInfo->operands[i] & Opr_Dest )
|
||||
asmcode->clobbersMemory = 1;
|
||||
}
|
||||
@@ -2218,8 +2208,7 @@ namespace AsmParserx8632
|
||||
}
|
||||
}
|
||||
|
||||
asmcode->insnTemplateLen = insnTemplate->offset;
|
||||
asmcode->insnTemplate = ( char* ) insnTemplate->extractData();
|
||||
asmcode->insnTemplate = insnTemplate.str();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2891,9 +2880,9 @@ namespace AsmParserx8632
|
||||
//FIXME: This printf is not portable. The use of `align` varies from system to system;
|
||||
// on i386 using a.out, .align `n` will align on a 2^`n` boundary instead of an `n` boundary
|
||||
#ifdef HAVE_GAS_BALIGN_AND_P2ALIGN
|
||||
insnTemplate->printf ( ".balign\t%u", ( unsigned ) align );
|
||||
insnTemplate << ".balign\t" << align;
|
||||
#else
|
||||
insnTemplate->printf ( ".align\t%u", ( unsigned ) align );
|
||||
insnTemplate << ".align\t" << align;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
@@ -2908,9 +2897,9 @@ namespace AsmParserx8632
|
||||
{
|
||||
// .align for GAS is in bits, others probably use bytes..
|
||||
#ifdef HAVE_GAS_BALIGN_AND_P2ALIGN
|
||||
insnTemplate->writestring ( ( char * ) ".align\t2" );
|
||||
insnTemplate << ".align\t2";
|
||||
#else
|
||||
insnTemplate->writestring ( ( char * ) ".align\t2" );
|
||||
insnTemplate << ".align\t2";
|
||||
#endif
|
||||
setAsmCode();
|
||||
}
|
||||
|
||||
101
gen/asm-x86-64.h
101
gen/asm-x86-64.h
@@ -1328,7 +1328,7 @@ namespace AsmParserx8664
|
||||
Scope * sc;
|
||||
|
||||
Token * token;
|
||||
OutBuffer * insnTemplate;
|
||||
std::ostringstream insnTemplate;
|
||||
|
||||
AsmOp op;
|
||||
AsmOpInfo * opInfo;
|
||||
@@ -1341,7 +1341,6 @@ namespace AsmParserx8664
|
||||
this->sc = sc;
|
||||
this->stmt = stmt;
|
||||
token = stmt->tokens;
|
||||
insnTemplate = new OutBuffer;
|
||||
|
||||
opInfo = NULL;
|
||||
|
||||
@@ -1572,8 +1571,7 @@ namespace AsmParserx8664
|
||||
void setAsmCode()
|
||||
{
|
||||
AsmCode * asmcode = new AsmCode ( N_Regs );
|
||||
asmcode->insnTemplateLen = insnTemplate->offset;
|
||||
asmcode->insnTemplate = ( char* ) insnTemplate->extractData();
|
||||
asmcode->insnTemplate = insnTemplate.str();
|
||||
stmt->asmcode = ( code* ) asmcode;
|
||||
}
|
||||
|
||||
@@ -1635,9 +1633,9 @@ namespace AsmParserx8664
|
||||
{
|
||||
case Arg_Integer:
|
||||
if ( e->type->isunsigned() )
|
||||
insnTemplate->printf ( "$%llu", e->toUInteger() );
|
||||
insnTemplate << "$" << e->toUInteger();
|
||||
else
|
||||
insnTemplate->printf ( "$%lld", e->toInteger() );
|
||||
insnTemplate << "$" << e->toInteger();
|
||||
break;
|
||||
|
||||
case Arg_Pointer:
|
||||
@@ -1658,10 +1656,10 @@ namespace AsmParserx8664
|
||||
|
||||
// osx needs an extra underscore
|
||||
if ( global.params.os == OSMacOSX )
|
||||
insnTemplate->writestring ( "_" );
|
||||
insnTemplate << "_";
|
||||
|
||||
// print out the mangle
|
||||
insnTemplate->writestring ( vd->mangle() );
|
||||
insnTemplate << vd->mangle();
|
||||
vd->nakedUse = true;
|
||||
break;
|
||||
}
|
||||
@@ -1676,25 +1674,23 @@ namespace AsmParserx8664
|
||||
}
|
||||
else
|
||||
{
|
||||
insnTemplate->writestring ( ( char* ) fmt );
|
||||
insnTemplate->printf ( "<<%s%d>>", ( mode==Mode_Input ) ?"in":"out", asmcode->args.size() );
|
||||
insnTemplate << fmt
|
||||
<< "<<" << (mode==Mode_Input ? "in" : "out") << asmcode->args.size() << ">>";
|
||||
asmcode->args.push_back ( AsmArg ( type, e, mode ) );
|
||||
}
|
||||
}
|
||||
void addOperand2 ( const char * fmtpre, const char * fmtpost, AsmArgType type, Expression * e, AsmCode * asmcode, AsmArgMode mode = Mode_Input )
|
||||
{
|
||||
assert ( !sc->func->naked );
|
||||
insnTemplate->writestring ( ( char* ) fmtpre );
|
||||
insnTemplate->printf ( "<<%s%d>>", ( mode==Mode_Input ) ?"in":"out", asmcode->args.size() );
|
||||
insnTemplate->writestring ( ( char* ) fmtpost );
|
||||
insnTemplate << fmtpre
|
||||
<< "<<" << (mode==Mode_Input ? "in" : "out") << ">>"
|
||||
<< fmtpost;
|
||||
asmcode->args.push_back ( AsmArg ( type, e, mode ) );
|
||||
}
|
||||
|
||||
void addLabel ( char* id )
|
||||
{
|
||||
insnTemplate->writestring ( sc->func->mangle() );
|
||||
insnTemplate->writestring ( "_" );
|
||||
insnTemplate->writestring ( id );
|
||||
insnTemplate << sc->func->mangle() << "_" << id;
|
||||
}
|
||||
|
||||
/* Determines whether the operand is a register, memory reference
|
||||
@@ -1778,8 +1774,7 @@ namespace AsmParserx8664
|
||||
|
||||
void writeReg ( Reg reg )
|
||||
{
|
||||
insnTemplate->writestring ( ( char* ) "%" );
|
||||
insnTemplate->write ( regInfo[reg].gccName.c_str(), regInfo[reg].gccName.length() );
|
||||
insnTemplate << "%" << regInfo[reg].gccName;
|
||||
}
|
||||
|
||||
bool opTakesLabel()
|
||||
@@ -1852,7 +1847,7 @@ namespace AsmParserx8664
|
||||
bool use_star;
|
||||
AsmArgMode mode;
|
||||
|
||||
insnTemplate = new OutBuffer;
|
||||
insnTemplate.str("");
|
||||
// %% todo: special case for something..
|
||||
if ( opInfo->linkType == Out_Mnemonic )
|
||||
mnemonic = alternateMnemonics[opInfo->link];
|
||||
@@ -1921,7 +1916,7 @@ namespace AsmParserx8664
|
||||
else if ( op == Op_Branch )
|
||||
{
|
||||
if ( operands[0].dataSize == Far_Ptr ) // %% type=Far_Ptr not set by Seg:Ofss OTOH, we don't support that..
|
||||
insnTemplate->writebyte ( 'l' );
|
||||
insnTemplate << 'l';
|
||||
}
|
||||
else if ( op == Op_fxch || op == Op_FfdRR_P || op == Op_FidR_P )
|
||||
{
|
||||
@@ -1959,11 +1954,10 @@ namespace AsmParserx8664
|
||||
{
|
||||
int mlen = strlen ( mnemonic );
|
||||
if ( mnemonic[mlen-1] == 'd' )
|
||||
insnTemplate->write ( mnemonic, mlen-1 );
|
||||
insnTemplate.write(mnemonic, mlen-1);
|
||||
else
|
||||
{
|
||||
insnTemplate->writestring ( ( char* ) mnemonic );
|
||||
insnTemplate->writebyte ( 'w' );
|
||||
insnTemplate << mnemonic << 'w';
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1978,12 +1972,11 @@ namespace AsmParserx8664
|
||||
int mlen = strlen ( mnemonic );
|
||||
if ( mnemonic[mlen-1] == 'd' )
|
||||
{
|
||||
insnTemplate->write ( mnemonic, mlen-1 );
|
||||
insnTemplate->writebyte ( 'l' );
|
||||
insnTemplate.write(mnemonic, mlen-1) << 'l';
|
||||
}
|
||||
else
|
||||
{
|
||||
insnTemplate->writestring ( ( char* ) mnemonic );
|
||||
insnTemplate << mnemonic;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -2010,15 +2003,13 @@ namespace AsmParserx8664
|
||||
return false;
|
||||
}
|
||||
assert ( type_char != 0 );
|
||||
insnTemplate->write ( mnemonic, mlen-1 );
|
||||
insnTemplate->writebyte ( tc_1 );
|
||||
insnTemplate->writebyte ( type_char );
|
||||
insnTemplate.write(mnemonic, mlen-1) << tc_1 << type_char;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
insnTemplate->writestring ( ( char* ) mnemonic );
|
||||
insnTemplate << mnemonic;
|
||||
if ( type_char )
|
||||
insnTemplate->writebyte ( type_char );
|
||||
insnTemplate << type_char;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2072,12 +2063,12 @@ namespace AsmParserx8664
|
||||
asmcode->regs[Reg_EDX] = true;
|
||||
}
|
||||
|
||||
insnTemplate->writebyte ( ' ' );
|
||||
insnTemplate << ' ';
|
||||
for ( int i__ = 0; i__ < nOperands; i__++ )
|
||||
{
|
||||
int i;
|
||||
if ( i__ != 0 )
|
||||
insnTemplate->writestring ( ( char* ) ", " );
|
||||
insnTemplate << ", ";
|
||||
|
||||
fmt = "$";
|
||||
|
||||
@@ -2125,7 +2116,7 @@ namespace AsmParserx8664
|
||||
addOperand ( "$", Arg_LocalSize,
|
||||
( Expression * ) operand->symbolDisplacement.data[0], asmcode );
|
||||
if ( operand->constDisplacement )
|
||||
insnTemplate->writebyte ( '+' );
|
||||
insnTemplate << '+';
|
||||
else
|
||||
break;
|
||||
}
|
||||
@@ -2138,7 +2129,7 @@ namespace AsmParserx8664
|
||||
asmcode );
|
||||
|
||||
if ( operand->constDisplacement )
|
||||
insnTemplate->writebyte ( '+' );
|
||||
insnTemplate << '+';
|
||||
else
|
||||
// skip the addOperand(fmt, Arg_Integer...) below
|
||||
break;
|
||||
@@ -2155,11 +2146,11 @@ namespace AsmParserx8664
|
||||
}
|
||||
}
|
||||
if ( opTakesLabel() /*opInfo->takesLabel()*/ )
|
||||
insnTemplate->writebyte ( '*' );
|
||||
insnTemplate << '*';
|
||||
writeReg ( operand->reg );
|
||||
/*
|
||||
insnTemplate->writestring("%");
|
||||
insnTemplate->writestring(regInfo[operand->reg].name);
|
||||
insnTemplate << "%";
|
||||
insnTemplate << regInfo[operand->reg].name;
|
||||
*/
|
||||
break;
|
||||
case Opr_Mem:
|
||||
@@ -2183,8 +2174,7 @@ namespace AsmParserx8664
|
||||
{
|
||||
if ( operand->symbolDisplacement.dim )
|
||||
{
|
||||
insnTemplate->printf ( "%d", operand->constDisplacement );
|
||||
insnTemplate->writebyte ( '+' );
|
||||
insnTemplate << operand->constDisplacement << '+';
|
||||
}
|
||||
//addOperand(fmt, Arg_Integer, newIntExp(operand->constDisplacement), asmcode);
|
||||
if ( opInfo->operands[i] & Opr_Dest )
|
||||
@@ -2194,7 +2184,7 @@ namespace AsmParserx8664
|
||||
if ( operand->segmentPrefix != Reg_Invalid )
|
||||
{
|
||||
writeReg ( operand->segmentPrefix );
|
||||
insnTemplate->writebyte ( ':' );
|
||||
insnTemplate << ':';
|
||||
}
|
||||
if ( operand->symbolDisplacement.dim )
|
||||
{
|
||||
@@ -2285,15 +2275,15 @@ namespace AsmParserx8664
|
||||
// simply write out the mangle
|
||||
// on osx, prepend extra _
|
||||
if ( global.params.os == OSMacOSX )
|
||||
insnTemplate->writestring ( "_" );
|
||||
insnTemplate->writestring ( decl->mangle() );
|
||||
insnTemplate << "_";
|
||||
insnTemplate << decl->mangle();
|
||||
// addOperand2("${", ":c}", Arg_Pointer, e, asmcode);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( use_star )
|
||||
{
|
||||
insnTemplate->writebyte ( '*' );
|
||||
insnTemplate << '*';
|
||||
use_star = false;
|
||||
}
|
||||
|
||||
@@ -2309,28 +2299,28 @@ namespace AsmParserx8664
|
||||
}
|
||||
}
|
||||
if ( use_star )
|
||||
insnTemplate->writebyte ( '*' );
|
||||
insnTemplate << '*';
|
||||
if ( operand->segmentPrefix != Reg_Invalid && !(operand->constDisplacement))
|
||||
{
|
||||
insnTemplate->printf ( "%d", operand->constDisplacement );
|
||||
insnTemplate << operand->constDisplacement;
|
||||
if ( opInfo->operands[i] & Opr_Dest )
|
||||
asmcode->clobbersMemory = 1;
|
||||
}
|
||||
if ( operand->baseReg != Reg_Invalid || operand->indexReg != Reg_Invalid )
|
||||
{
|
||||
insnTemplate->writebyte ( '(' );
|
||||
insnTemplate << '(';
|
||||
if ( operand->baseReg != Reg_Invalid )
|
||||
writeReg ( operand->baseReg );
|
||||
if ( operand->indexReg != Reg_Invalid )
|
||||
{
|
||||
insnTemplate->writebyte ( ',' );
|
||||
insnTemplate << ',';
|
||||
writeReg ( operand->indexReg );
|
||||
if ( operand->scale )
|
||||
{
|
||||
insnTemplate->printf ( ",%d", operand->scale );
|
||||
insnTemplate << "," << operand->scale;
|
||||
}
|
||||
}
|
||||
insnTemplate->writebyte ( ')' );
|
||||
insnTemplate << ')';
|
||||
if ( opInfo->operands[i] & Opr_Dest )
|
||||
asmcode->clobbersMemory = 1;
|
||||
}
|
||||
@@ -2340,8 +2330,7 @@ namespace AsmParserx8664
|
||||
}
|
||||
}
|
||||
|
||||
asmcode->insnTemplateLen = insnTemplate->offset;
|
||||
asmcode->insnTemplate = ( char* ) insnTemplate->extractData();
|
||||
asmcode->insnTemplate = insnTemplate.str();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -3016,9 +3005,9 @@ namespace AsmParserx8664
|
||||
//FIXME: This printf is not portable. The use of `align` varies from system to system;
|
||||
// on i386 using a.out, .align `n` will align on a 2^`n` boundary instead of an `n` boundary
|
||||
#ifdef HAVE_GAS_BALIGN_AND_P2ALIGN
|
||||
insnTemplate->printf ( ".balign\t%u", ( unsigned ) align );
|
||||
insnTemplate << ".balign\t" << align;
|
||||
#else
|
||||
insnTemplate->printf ( ".align\t%u", ( unsigned ) align );
|
||||
insnTemplate << ".align\t" << align;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
@@ -3033,9 +3022,9 @@ namespace AsmParserx8664
|
||||
{
|
||||
// .align for GAS is in bits, others probably use bytes..
|
||||
#ifdef HAVE_GAS_BALIGN_AND_P2ALIGN
|
||||
insnTemplate->writestring ( ( char * ) ".align\t2" );
|
||||
insnTemplate << ".align\t2";
|
||||
#else
|
||||
insnTemplate->writestring ( ( char * ) ".align\t2" );
|
||||
insnTemplate << ".align\t2";
|
||||
#endif
|
||||
setAsmCode();
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
#include <cassert>
|
||||
#include <deque>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
//#include "d-lang.h"
|
||||
//#include "d-codegen.h"
|
||||
@@ -54,15 +56,12 @@ struct AsmArg {
|
||||
};
|
||||
|
||||
struct AsmCode {
|
||||
char * insnTemplate;
|
||||
unsigned insnTemplateLen;
|
||||
std::string insnTemplate;
|
||||
std::vector<AsmArg> args;
|
||||
std::vector<bool> regs;
|
||||
unsigned dollarLabel;
|
||||
int clobbersMemory;
|
||||
AsmCode(int n_regs) {
|
||||
insnTemplate = NULL;
|
||||
insnTemplateLen = 0;
|
||||
regs.resize(n_regs, false);
|
||||
dollarLabel = 0;
|
||||
clobbersMemory = 0;
|
||||
@@ -314,7 +313,6 @@ assert(0);
|
||||
clobbers.push_back(memory_name);
|
||||
// }
|
||||
|
||||
|
||||
// Remap argument numbers
|
||||
for (unsigned i = 0; i < code->args.size(); i++) {
|
||||
if (arg_map[i] < 0)
|
||||
@@ -322,8 +320,9 @@ assert(0);
|
||||
}
|
||||
|
||||
bool pct = false;
|
||||
char * p = code->insnTemplate;
|
||||
char * q = p + code->insnTemplateLen;
|
||||
std::string::iterator
|
||||
p = code->insnTemplate.begin(),
|
||||
q = code->insnTemplate.end();
|
||||
//printf("start: %.*s\n", code->insnTemplateLen, code->insnTemplate);
|
||||
while (p < q) {
|
||||
if (pct) {
|
||||
@@ -342,7 +341,7 @@ assert(0);
|
||||
|
||||
typedef std::vector<std::string>::iterator It;
|
||||
if (Logger::enabled()) {
|
||||
Logger::println("final asm: %.*s", code->insnTemplateLen, code->insnTemplate);
|
||||
Logger::cout() << "final asm: " << code->insnTemplate << '\n';
|
||||
std::ostringstream ss;
|
||||
|
||||
ss << "GCC-style output constraints: {";
|
||||
@@ -369,8 +368,6 @@ assert(0);
|
||||
Logger::println("%s", ss.str().c_str());
|
||||
}
|
||||
|
||||
std::string insnt(code->insnTemplate, code->insnTemplateLen);
|
||||
|
||||
// rewrite GCC-style constraints to LLVM-style constraints
|
||||
std::string llvmOutConstraints;
|
||||
std::string llvmInConstraints;
|
||||
@@ -433,7 +430,7 @@ assert(0);
|
||||
|
||||
// push asm statement
|
||||
IRAsmStmt* asmStmt = new IRAsmStmt;
|
||||
asmStmt->code = insnt;
|
||||
asmStmt->code = code->insnTemplate;
|
||||
asmStmt->out_c = llvmOutConstraints;
|
||||
asmStmt->in_c = llvmInConstraints;
|
||||
asmStmt->out.insert(asmStmt->out.begin(), output_values.begin(), output_values.end());
|
||||
@@ -825,10 +822,7 @@ void AsmStatement::toNakedIR(IRState *p)
|
||||
AsmCode * code = (AsmCode *) asmcode;
|
||||
|
||||
// build asm stmt
|
||||
std::ostringstream& asmstr = p->nakedAsm;
|
||||
asmstr << "\t";
|
||||
asmstr.write(code->insnTemplate, code->insnTemplateLen);
|
||||
asmstr << std::endl;
|
||||
p->nakedAsm << "\t" << code->insnTemplate << std::endl;
|
||||
}
|
||||
|
||||
void AsmBlockStatement::toNakedIR(IRState *p)
|
||||
|
||||
Reference in New Issue
Block a user