diff gen/asm-x86-64.h @ 1102:ae950bd712d3

Use stringstream in asm generation instead of OutBuffer. Besides looking better, this should reduce allocations and copying.
author Frits van Bommel <fvbommel wxs.nl>
date Thu, 12 Mar 2009 14:08:57 +0100
parents 8bf8b058944a
children d03814546977
line wrap: on
line diff
--- a/gen/asm-x86-64.h	Thu Mar 12 14:08:57 2009 +0100
+++ b/gen/asm-x86-64.h	Thu Mar 12 14:08:57 2009 +0100
@@ -1328,7 +1328,7 @@
         Scope * sc;
 
         Token * token;
-        OutBuffer * insnTemplate;
+        std::ostringstream insnTemplate;
 
         AsmOp       op;
         AsmOpInfo * opInfo;
@@ -1341,7 +1341,6 @@
             this->sc = sc;
             this->stmt = stmt;
             token = stmt->tokens;
-            insnTemplate = new OutBuffer;
 
             opInfo = NULL;
 
@@ -1572,8 +1571,7 @@
         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 @@
                 {
                     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 @@
 
                                 // 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 @@
             }
             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 @@
 
         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 @@
             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 @@
             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 @@
                 {
                     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 @@
                     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 @@
                             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 @@
                 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 @@
                             addOperand ( "$", Arg_LocalSize,
                                          ( Expression * ) operand->symbolDisplacement.data[0], asmcode );
                             if ( operand->constDisplacement )
-                                insnTemplate->writebyte ( '+' );
+                                insnTemplate << '+';
                             else
                                 break;
                         }
@@ -2138,7 +2129,7 @@
                                          asmcode );
 
                             if ( operand->constDisplacement )
-                                insnTemplate->writebyte ( '+' );
+                                insnTemplate << '+';
                             else
                                 // skip the addOperand(fmt, Arg_Integer...) below
                                 break;
@@ -2155,11 +2146,11 @@
                             }
                         }
                         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 @@
                         {
                             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 @@
                         if ( operand->segmentPrefix != Reg_Invalid )
                         {
                             writeReg ( operand->segmentPrefix );
-                            insnTemplate->writebyte ( ':' );
+                            insnTemplate << ':';
                         }
                         if ( operand->symbolDisplacement.dim )
                         {
@@ -2285,15 +2275,15 @@
                                     // 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 @@
                             }
                         }
                         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 @@
                 }
             }
 
-            asmcode->insnTemplateLen = insnTemplate->offset;
-            asmcode->insnTemplate = ( char* ) insnTemplate->extractData();
+            asmcode->insnTemplate = insnTemplate.str();
             return true;
         }
 
@@ -3016,9 +3005,9 @@
                 //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 @@
         {
             // .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();
         }