00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include "c_breeze.h"
00040 #include "arch_info.h"
00041 #include "arch_info_parser.h"
00042 #include "lirutil.h"
00043
00044
00045 typedef arch_info::register_info register_info;
00046 typedef arch_info::register_info_list register_info_list;
00047
00048
00049 register_info arch_info::pseudo_reg_dest( (unsigned int)-2, "dest" );
00050 register_info arch_info::pseudo_reg_src1( (unsigned int)-4, "src1" );
00051 register_info arch_info::pseudo_reg_src2( (unsigned int)-5, "src2" );
00052
00053
00054
00055 #define PARSE_ERROR( format ) \
00056 CBZ::Fail( __FILE__, __LINE__, \
00057 cbz_util::string_format( "error parsing architecture spec"\
00058 " (near line %d): ", _currentLine ));
00059
00060 arch_info::arch_info() {
00061
00062 _nextRegId = 0;
00063
00064
00065 reset_info();
00066 }
00067
00068 arch_info::~arch_info()
00069 {}
00070
00071 void
00072 arch_info::reset_info() {
00073
00074 _valid = false;
00075
00076
00077 _asmLineComment.clear();
00078 _asmRegPrefixAdd.clear();
00079 _asmRegPrefixRemove.clear();
00080 _asmRegPrefixRemoveSplit.clear();
00081 _asmConstPrefix.clear();
00082 _regsAll.clear();
00083 _regMap.clear();
00084 _regsGpr.clear();
00085 _regsFpr.clear();
00086 _regSp = NULL;
00087 _regFp = NULL;
00088 _regsParamFixed.clear();
00089 _regsParamFloat.clear();
00090 _regRetvalFixed = NULL;
00091 _regRetvalFloat = NULL;
00092 _regDataTypeGpr = NULL;
00093 _regDataTypeFpr = NULL;
00094 _dataSizeLong = 8;
00095 _dataSizeInt = 4;
00096 _dataSizeShort= 2;
00097 _dataSizeDouble = 8;
00098 _dataSizeFloat = 4;
00099 _dataSizePtr = 4;
00100 _maxDataAlign = (unsigned int)-1;
00101 _dataAlignChar = 1;
00102 _dataAlignShort = 2;
00103 _dataAlignInt = 4;
00104 _dataAlignLong = 8;
00105 _dataAlignFloat = 4;
00106 _dataAlignDouble = 8;
00107 _dataAlignPtr = 4;
00108 _stackFrameMinSize = 0;
00109 _stackExtraTop = 0;
00110 _stackExtraBottom = 0;
00111 _stackAlign = 0;
00112 _stackFormalsOffset = 0;
00113 _emulate3Address = false;
00114 _Lir2Asm_records.clear();
00115 _Lir2Asm_mnemonicLookup.clear();
00116 }
00117
00118 const char *
00119 arch_info::get_asm_line_comment() const {
00120 return _asmLineComment.c_str();
00121 }
00122
00123 const char *
00124 arch_info::get_asm_const_prefix() const {
00125 return _asmConstPrefix.c_str();
00126 }
00127
00128 const register_info_list &
00129 arch_info::get_all_regs() const {
00130 return _regsAll;
00131 }
00132
00133 const register_info_list &
00134 arch_info::get_regs_gpr() const {
00135 return _regsGpr;
00136 }
00137
00138 const register_info_list &
00139 arch_info::get_regs_fpr() const {
00140 return _regsFpr;
00141 }
00142
00143 const register_info*
00144 arch_info::get_reg_sp() const {
00145 return _regSp;
00146 }
00147
00148 const register_info*
00149 arch_info::get_reg_fp() const {
00150 return _regFp;
00151 }
00152
00153 const register_info_list &
00154 arch_info::get_regs_param_fixed() const {
00155 return _regsParamFixed;
00156 }
00157
00158 const register_info_list &
00159 arch_info::get_regs_param_float() const {
00160 return _regsParamFloat;
00161 }
00162
00163 const register_info*
00164 arch_info::get_reg_retval_fixed() const {
00165 return _regRetvalFixed;
00166 }
00167
00168 const register_info*
00169 arch_info::get_reg_retval_float() const {
00170 return _regRetvalFloat;
00171 }
00172
00173 const register_info_list &
00174 arch_info::get_regs_caller_save() const {
00175 return _regsCallerSave;
00176 }
00177
00178 const register_info_list &
00179 arch_info::get_regs_callee_save() const {
00180 return _regsCalleeSave;
00181 }
00182
00183 typeNode *
00184 arch_info::get_reg_data_type_gpr() const {
00185 return _regDataTypeGpr;
00186 }
00187
00188 typeNode *
00189 arch_info::get_reg_data_type_fpr() const {
00190 return _regDataTypeFpr;
00191 }
00192
00193 bool
00194 arch_info::get_reg_name( const Register & reg, string & name,
00195 bool wantPrefixAdd, bool wantPrefixRemove ) {
00196
00197 int num = reg.num();
00198 if ( num < 0 || num >= (int)_regsAll.size() )
00199 return false;
00200
00201
00202 name = _regsAll[num]->_name;
00203 if ( wantPrefixAdd )
00204 name = _asmRegPrefixAdd + name;
00205 if ( wantPrefixRemove )
00206 for ( size_t i = 0; i < _asmRegPrefixRemoveSplit.size(); ++i )
00207 if ( name.find( _asmRegPrefixRemoveSplit[i] ) == 0 )
00208 name.erase( 0, _asmRegPrefixRemoveSplit[i].size() );
00209 return true;
00210 }
00211
00212 bool
00213 arch_info::get_reg_by_index( int realRegIndex, Register & reg )
00214 {
00215
00216 if ( realRegIndex < 0 || realRegIndex >= (int)_regsAll.size() )
00217 return false;
00218
00219
00220 reg = get_register( _regsAll[realRegIndex] );
00221 return true;
00222 }
00223
00224
00225 unsigned int
00226 arch_info::get_data_size( typeNode * the_type ) const
00227 {
00228 if ( the_type->is_pointer() )
00229 return get_data_size_ptr();
00230 if ( primNode * primType = dynamic_cast<primNode *>(the_type) ) {
00231 if ( primType->is_float() )
00232 if ( primType->basic().is_long() )
00233 return get_data_size_double();
00234 else
00235 return get_data_size_float();
00236 else if ( primType->is_char() )
00237 return 1;
00238 else if ( primType->is_integer() )
00239 if ( primType->basic().is_short() )
00240 return get_data_size_short();
00241 else if ( primType->basic().is_long() )
00242 return get_data_size_long();
00243 else
00244 return get_data_size_int();
00245 }
00246 return 0;
00247 }
00248
00249 unsigned int
00250 arch_info::get_max_data_align() const
00251 {
00252
00253 if ( _maxDataAlign != -1 )
00254 return _maxDataAlign;
00255
00256
00257 _maxDataAlign = _dataAlignChar;
00258 if ( _maxDataAlign < _dataAlignShort )
00259 _maxDataAlign = _dataAlignShort;
00260 if ( _maxDataAlign < _dataAlignInt )
00261 _maxDataAlign = _dataAlignInt;
00262 if ( _maxDataAlign < _dataAlignLong )
00263 _maxDataAlign = _dataAlignLong;
00264 if ( _maxDataAlign < _dataAlignFloat )
00265 _maxDataAlign = _dataAlignFloat;
00266 if ( _maxDataAlign < _dataAlignDouble )
00267 _maxDataAlign = _dataAlignDouble;
00268 if ( _maxDataAlign < _dataAlignPtr )
00269 _maxDataAlign = _dataAlignPtr;
00270
00271 return _maxDataAlign;
00272 }
00273
00274
00275 unsigned int
00276 arch_info::get_data_align( typeNode * the_type ) const
00277 {
00278 if ( the_type->is_pointer() )
00279 return get_data_align_ptr();
00280 if ( the_type->is_aggregate() )
00281 return get_max_data_align();
00282 if ( primNode * primType = dynamic_cast<primNode *>(the_type) ) {
00283 if ( primType->is_float() )
00284 if ( primType->basic().is_long() )
00285 return get_data_align_double();
00286 else
00287 return get_data_align_float();
00288 else if ( primType->is_char() )
00289 return get_data_align_char();
00290 else if ( primType->is_integer() )
00291 if ( primType->basic().is_short() )
00292 return get_data_align_short();
00293 else if ( primType->basic().is_long() )
00294 return get_data_align_long();
00295 else
00296 return get_data_align_int();
00297 }
00298 return 0;
00299 }
00300
00301 bool
00302 arch_info::get_code_for_instruction( const LirInst * pInst,
00303 vector<string> & lines )
00304 {
00305
00306 Lir2Asm * pLir2Asm = NULL;
00307 if ( ! get_Lir2Asm_for_instruction( pInst, &pLir2Asm ) || ! pLir2Asm )
00308 return false;
00309
00310
00311 cbz_util::vector_copy( pLir2Asm->_codeTemplate, lines );
00312
00313
00314 make_template_replacements( pInst, pLir2Asm, lines );
00315
00316
00317
00318 if ( pInst->instruction != mn_Label ) {
00319 int i, sz = (int)lines.size();
00320 for ( i = 0; i < sz; ++i ) {
00321
00322
00323 if ( lines[i].find( ':' ) == -1 )
00324 lines[i].insert( 0, 4, ' ' );
00325 }
00326 }
00327
00328 return true;
00329 }
00330
00331 bool
00332 arch_info::get_instruction_kill_regs( const LirInst * pInst,
00333 register_info_list & killRegs )
00334 {
00335
00336 Lir2Asm * pLir2Asm = NULL;
00337 if ( ! get_Lir2Asm_for_instruction( pInst, &pLir2Asm ) || ! pLir2Asm )
00338 return false;
00339
00340
00341 cbz_util::vector_copy( pLir2Asm->_killRegs, killRegs );
00342
00343 return true;
00344 }
00345
00346 bool
00347 arch_info::types_need_conversion( typeNode * srcType, typeNode * destType )
00348 {
00349
00350
00351 Lir2Asm * l2a = NULL;
00352 if ( ! get_Lir2Asm_for_instruction( mn_ConvertType, srcType, destType,
00353 false, &l2a )
00354 || ! l2a )
00355 return true;
00356
00357
00358 return (l2a->_codeTemplate.size() != 0);
00359 }
00360
00361 bool
00362 arch_info::instruction_supports_immediate( mnemonic instruction,
00363 typeNode * the_type,
00364 const constant & c )
00365 {
00366
00367 if ( c.is_str() )
00368 return false;
00369
00370
00371 Lir2Asm * l2a = NULL;
00372 return ( get_Lir2Asm_for_instruction( instruction, the_type, NULL,
00373 true, &l2a )
00374 && l2a != NULL );
00375 }
00376
00377 bool
00378 arch_info::find_register_info( const char * name,
00379 register_info *& regInfoFound ) const
00380 {
00381
00382 register_info_map::const_iterator it = _regMap.find( name );
00383 if ( it == _regMap.end() )
00384 return false;
00385
00386
00387 regInfoFound = (*it).second;
00388 return true;
00389 }
00390
00391 Register
00392 arch_info::get_register( const register_info * pInfo )
00393 {
00394
00395 Register ret;
00396 if ( ! pInfo )
00397 return ret;
00398
00399
00400 ret.num( pInfo->_id );
00401 ret.type( pInfo->_type );
00402 return ret;
00403 }
00404
00405 bool
00406 arch_info::get_Lir2Asm_for_instruction( const LirInst * pInst,
00407 Lir2Asm ** ppLir2Asm )
00408 {
00409
00410 return get_Lir2Asm_for_instruction( pInst->instruction, pInst->primaryType,
00411 pInst->convertType,
00412 pInst->opnd2._is_const, ppLir2Asm );
00413 }
00414
00415 bool
00416 arch_info::get_Lir2Asm_for_instruction( mnemonic inst, typeNode * srcType,
00417 typeNode * destType, bool isImmed,
00418 Lir2Asm ** ppLir2Asm )
00419 {
00420
00421 map_menmonic_to_record_set::const_iterator it =
00422 _Lir2Asm_mnemonicLookup.find( inst );
00423 if ( it == _Lir2Asm_mnemonicLookup.end() )
00424 return false;
00425
00426
00427 const vector<int> & possibles = it->second;
00428 int sz = (int)possibles.size();
00429 for ( int i = 0; i < sz; ++i ) {
00430
00431 assert( possibles[i] >= 0 && possibles[i] < (int)_Lir2Asm_records.size() );
00432
00433 Lir2Asm & l2a = _Lir2Asm_records[ possibles[i] ];
00434
00435
00436 assert(find(l2a._lirInstTypes.begin(),
00437 l2a._lirInstTypes.end(),
00438 inst) != l2a._lirInstTypes.end());
00439
00440
00441 if ( l2a._immed != Lir2Asm::Immed_NA ) {
00442
00443 if ( l2a._immed == Lir2Asm::Immed_No && isImmed )
00444 continue;
00445 else if ( l2a._immed == Lir2Asm::Immed_Yes && ! isImmed )
00446 continue;
00447 }
00448
00449
00450
00451 if ( srcType && l2a._dataTypes.size() > 0
00452 && !findType(l2a._dataTypes, srcType) )
00453 continue;
00454
00455
00456 if ( destType
00457 && !findType(l2a._convertToTypes, destType) )
00458 continue;
00459
00460
00461 *ppLir2Asm = &l2a;
00462 return true;
00463 }
00464
00465 return false;
00466 }
00467
00468 bool arch_info::findType(vector<typeNode *> & types, typeNode * toFind) {
00469 assert(toFind);
00470 if ( toFind->is_pointer() ) {
00471
00472
00473 toFind = LirUtil::newVoidPtr();
00474 }
00475
00476 for ( int i = 0; i < types.size(); i++ ) {
00477 if ( *toFind == *(types[i]) )
00478 return true;
00479 }
00480 return false;
00481 }
00482
00483 void
00484 arch_info::make_template_replacements( const LirInst * pInst,
00485 Lir2Asm * pLir2Asm,
00486 code_template & outputTemplate )
00487 {
00488
00489 string dest, op1, op2, base, offset, target, stacksize;
00490 string val, size, align;
00491 if ( pInst->has_dest() )
00492 dest = pInst->dest.to_string();
00493 if ( pInst->has_opnd1() )
00494 op1 = pInst->opnd1.to_string();
00495 if ( pInst->has_opnd2( false ) )
00496 op2 = pInst->opnd2.to_string( false, true );
00497 if ( pInst->has_base() )
00498 base = pInst->memBase.to_string();
00499 if ( pInst->has_offset( false ) )
00500 offset = pInst->memOffset.to_string( false, false );
00501 if ( pInst->nodeExtra && pInst->nodeExtra->typ() == Proc ) {
00502 procNode * the_proc = dynamic_cast<procNode *>(pInst->nodeExtra);
00503 assert(the_proc);
00504 stacksize = cbz_util::string_format( "%d", the_proc->stack_frame_size() );
00505 }
00506
00507
00508 target = pInst->target;
00509
00510 val = pInst->dataValue.to_string();
00511 size = cbz_util::string_format("%d", pInst->dataSize);
00512 align = cbz_util::string_format("%d", pInst->dataAlign);
00513
00514
00515 int i, sz = (int)outputTemplate.size();
00516 for ( i = 0; i < sz; ++i ) {
00517
00518 cbz_util::string_replace( outputTemplate[i], "$dest", dest );
00519 cbz_util::string_replace( outputTemplate[i], "$opnd1", op1 );
00520 cbz_util::string_replace( outputTemplate[i], "$opnd2", op2 );
00521 cbz_util::string_replace( outputTemplate[i], "$base", base );
00522 cbz_util::string_replace( outputTemplate[i], "$offset", offset );
00523 cbz_util::string_replace( outputTemplate[i], "$target", target );
00524 cbz_util::string_replace( outputTemplate[i], "$stacksize", stacksize );
00525
00526 cbz_util::string_replace( outputTemplate[i], "$value", val );
00527 cbz_util::string_replace( outputTemplate[i], "$size", size );
00528 cbz_util::string_replace( outputTemplate[i], "$align", align );
00529
00530
00531 int reg, szregs = (int)_regsAll.size();
00532 for ( reg = 0; reg < szregs; ++reg ) {
00533 string handyName = '@' + _regsAll[reg]->_name;
00534 string realName;
00535 get_reg_name( *_regsAll[reg], realName, true, true );
00536 cbz_util::string_replace( outputTemplate[i], handyName, realName );
00537 }
00538 }
00539 }
00540
00541 bool
00542 arch_info::load_arch_info( const char * pFileName )
00543 {
00544 int i, sz;
00545
00546
00547 reset_info();
00548
00549
00550 arch_info_parser parser;
00551 if ( ! parser.parse( pFileName, this ) )
00552 return false;
00553
00555
00556
00557
00558 _regSp->_type = reg_stack_ptr;
00559 _regFp->_type = reg_frame_ptr;
00560 sz = (int)_regsGpr.size();
00561 for ( i = 0; i < sz; ++i )
00562 _regsGpr[i]->_type = reg_gpr;
00563 sz = (int)_regsFpr.size();
00564 for ( i = 0; i < sz; ++i )
00565 _regsFpr[i]->_type = reg_fpr;
00566
00568
00569
00570 #define ARCHWARN( expr ) \
00571 cout << cbz_util::string_format expr << endl;
00572
00573 if ( _regsAll.size() < 1 )
00574 ARCHWARN(( "WARNING: architecture does not appear to have any "
00575 "registers!!" ));
00576 if ( _regsGpr.size() < 1 )
00577 ARCHWARN(( "WARNING: architecture does not appear to have any integer "
00578 "registers!!" ));
00579 if ( ! _regSp || ! _regSp->is_valid() )
00580 ARCHWARN(( "WARNING: architecture does not appear to have a stack "
00581 "pointer register!!" ));
00582 if ( ! _regFp || ! _regFp->is_valid() )
00583 ARCHWARN(( "WARNING: architecture does not appear to have a frame "
00584 "pointer register!!" ));
00585 if ( ! _regDataTypeGpr )
00586 ARCHWARN(( "WARNING: invalid data type specified for general-purpose "
00587 "registers!!" ));
00588 if ( ! _regDataTypeFpr )
00589 ARCHWARN(( "WARNING: invalid data type specified for floating-point "
00590 "registers!!" ));
00591 if ( _dataSizeShort <= 0 )
00592 ARCHWARN(( "WARNING: size of short integer (%d) appears to be "
00593 "ridiculous!!", _dataSizeShort ));
00594 if ( _dataSizeInt <= 0 )
00595 ARCHWARN(( "WARNING: size of integer (%d) appears to be ridiculous!!",
00596 _dataSizeInt ));
00597 if ( _dataSizeLong <= 0 )
00598 ARCHWARN(( "WARNING: size of long integer (%d) appears to be ridiculous!!",
00599 _dataSizeLong ));
00600 if ( _dataSizeFloat <= 0 )
00601 ARCHWARN(( "WARNING: size of float (%d) appears to be ridiculous!!",
00602 _dataSizeFloat ));
00603 if ( _dataSizeDouble <= 0 )
00604 ARCHWARN(( "WARNING: size of double float (%d) appears to be ridiculous!!",
00605 _dataSizeDouble ));
00606 if ( _dataSizePtr <= 0 )
00607 ARCHWARN(( "WARNING: size of pointer (%d) appears to be ridiculous!!",
00608 _dataSizePtr ));
00609
00610
00611
00612 if ( sizeof(short) != _dataSizeShort )
00613 ARCHWARN(( "WARNING: compiler data size does not match target data "
00614 "size for type 'short'. "
00615 "This is currently not handled properly by the backend." ));
00616 if ( sizeof(int) != _dataSizeInt )
00617 ARCHWARN(( "WARNING: compiler data size does not match target data "
00618 "size for type 'int'. "
00619 "This is currently not handled properly by the backend." ));
00620 if ( sizeof(long) != _dataSizeLong )
00621 ARCHWARN(( "WARNING: compiler data size does not match target data "
00622 "size for type 'long'. "
00623 "This is currently not handled properly by the backend." ));
00624 if ( sizeof(float) != _dataSizeFloat )
00625 ARCHWARN(( "WARNING: compiler data size does not match target data "
00626 "size for type 'float'. "
00627 "This is currently not handled properly by the backend." ));
00628 if ( sizeof(double) != _dataSizeDouble )
00629 ARCHWARN(( "WARNING: compiler data size does not match target data "
00630 "size for type 'double'. "
00631 "This is currently not handled properly by the backend." ));
00632 if ( sizeof(void*) != _dataSizePtr )
00633 ARCHWARN(( "WARNING: compiler data size does not match target data "
00634 "size for type 'pointer'. "
00635 "This is currently not handled properly by the backend." ));
00636
00637 if ( _dataAlignChar <= 0 )
00638 ARCHWARN(( "WARNING: alignment of character (%d) appears to be "
00639 "ridiculous!!", _dataAlignChar ));
00640 if ( _dataAlignShort <= 0 )
00641 ARCHWARN(( "WARNING: alignment of short integer (%d) appears to be "
00642 "ridiculous!!", _dataAlignShort ));
00643 if ( _dataAlignInt <= 0 )
00644 ARCHWARN(( "WARNING: alignment of integer (%d) appears to be "
00645 "ridiculous!!", _dataAlignInt ));
00646 if ( _dataAlignLong <= 0 )
00647 ARCHWARN(( "WARNING: alignment of long integer (%d) appears to be "
00648 "ridiculous!!", _dataAlignLong ));
00649 if ( _dataAlignFloat <= 0 )
00650 ARCHWARN(( "WARNING: alignment of float (%d) appears to be ridiculous!!",
00651 _dataAlignFloat ));
00652 if ( _dataAlignDouble <= 0 )
00653 ARCHWARN(( "WARNING: alignment of double float (%d) appears to be "
00654 "ridiculous!!", _dataAlignDouble ));
00655 if ( _dataAlignPtr <= 0 )
00656 ARCHWARN(( "WARNING: alignment of pointer (%d) appears to be ridiculous!!",
00657 _dataAlignPtr ));
00658
00659 if ( _stackFrameMinSize < 0 )
00660 ARCHWARN(( "WARNING: stack frame minimum size (%d) appears to be "
00661 "ridiculous!!", _stackFrameMinSize ));
00662 if ( _stackAlign < 0 )
00663 ARCHWARN(( "WARNING: stack alignment value (%d) appears to be "
00664 "ridiculous!!", _stackAlign ));
00665
00666 if ( _stackFrameMinSize != 0
00667 && _stackAlign != 0
00668 && (_stackFrameMinSize % _stackAlign) != 0 )
00669 ARCHWARN(( "WARNING: stack frame minimum size is not a multiple of "
00670 "stack alignment!!" ));
00671
00672
00673
00674 register_info_list::iterator it = _regsAll.begin();
00675 for ( ; it != _regsAll.end(); ++it ) {
00676 register_info * info = *it;
00677 if ( ! info )
00678 continue;
00679
00680
00681 bool caller = false, callee = false;
00682
00683
00684 register_info_list::iterator calleeIt = _regsCalleeSave.begin();
00685 for ( ; calleeIt != _regsCalleeSave.end(); ++calleeIt )
00686 if ( info == *calleeIt ) {
00687 callee = true;
00688 break;
00689 }
00690
00691
00692 register_info_list::iterator callerIt = _regsCallerSave.begin();
00693 for ( ; callerIt != _regsCallerSave.end(); ++callerIt )
00694 if ( info == *callerIt ) {
00695 caller = true;
00696 break;
00697 }
00698
00699
00700 if ( ! caller
00701 && ! callee
00702 && info != _regFp
00703 && info != _regSp
00704 && info != _regRetvalFixed
00705 && info != _regRetvalFloat )
00706 ARCHWARN(( "WARNING: register %s is not caller-save or callee-save "
00707 "- is this the intent?", info->_name.c_str() ));
00708
00709
00710 if ( caller && callee )
00711 ARCHWARN(( "WARNING: register %s is both caller-save and callee-save "
00712 "- is this the intent?", info->_name.c_str() ));
00713
00714
00715
00716 if ( (caller || callee) && (info == _regFp || info == _regSp) )
00717 ARCHWARN(( "WARNING: register %s should be handled by architecture "
00718 "template because it is the frame/stack pointer.",
00719 info->_name.c_str() ));
00720
00721
00722
00723 if ( (caller || callee)
00724 && (info == _regRetvalFixed || info == _regRetvalFloat) )
00725 ARCHWARN(( "WARNING: return-value register %s is volatile and will "
00726 "not be saved even though marked as caller/callee save.",
00727 info->_name.c_str() ));
00728 }
00729
00730 #undef ARCHWARN
00731
00733
00734
00735
00736 if ( ! _asmRegPrefixRemove.empty() ) {
00737 int len = _asmRegPrefixRemove.size() + 2;
00738 char * split = new char[ len ];
00739 strcpy( split, _asmRegPrefixRemove.c_str() );
00740 split[ len-1 ] = 0;
00741 char *p1 = split, *p2 = strchr(p1, ',');
00742 while ( (p2 = strchr(p1, ',')) ) {
00743
00744 *p2 = 0;
00745 _asmRegPrefixRemoveSplit.push_back( p1 );
00746 p1 = p2 + 1;
00747 }
00748 _asmRegPrefixRemoveSplit.push_back( p1 );
00749 delete [] split;
00750 }
00751
00753
00754
00755
00756 cout << endl;
00757 cout << "will compile for architecture: " << _archName.c_str() << endl;
00758 cout << endl;
00759
00760
00761 _valid = true;
00762 return true;
00763 }