static void FixFarLocalRefs( type_length size ) { /**************************************************** Turn far local references into indexed references so that we can address all of our auto variables and parms. */ block *blk; instruction *ins; int i; int offset_size; name **offsets; i = size / _4K; offset_size = (i+1) * sizeof( name** ); offsets = CGAlloc( offset_size ); while( i >= 0 ) { offsets[ i ] = NULL; --i; } blk = HeadBlock; while( blk != NULL ) { ins = blk->ins.hd.next; while( ins->head.opcode != OP_BLOCK ) { i = ins->num_operands; while( --i >= 0 ) { CheckOp( offsets, ins, &ins->operands[ i ] ); } if( ins->result != NULL ) { CheckOp( offsets, ins, &ins->result ); } ins = ins->head.next; } blk = blk->next_block; } CGFree( offsets ); }
static void CheckOp( name **offsets, instruction *ins, name **pop ) { /************************************************************************ used by FixFarLocalRefs to change one far local reference to an index, using the appropriate multiple of 4K constant to get at the temporary. The constant values are adjusted after the prolog is generated. */ name *op; name *base; name *temp; unsigned_32 place; int i; instruction *new_ins; op = *pop; if( op->n.class == N_INDEXED ) { temp = op->i.index; if( temp->n.class != N_TEMP ) return; if( !( temp->t.temp_flags & FAR_LOCAL ) ) return; new_ins = MakeMove( temp, AllocTemp( temp->n.name_class ), temp->n.name_class ); *pop = ScaleIndex( new_ins->result, op->i.base, op->i.constant, op->n.class, op->n.size, op->i.scale, op->i.index_flags ); PrefixIns( ins, new_ins ); CheckOp( offsets, new_ins, &new_ins->operands[ 0 ] ); } if( op->n.class != N_TEMP ) return; if( !( op->t.temp_flags & FAR_LOCAL ) ) return; base = DeAlias( op ); place = base->t.location + ( op->v.offset - base->v.offset ); i = place/_4K; if( offsets[ i ] == NULL ) { /*set the symbol field in the AddrConst to non-NULL for score-boarder*/ new_ins = MakeMove( AllocAddrConst( (name *)&CurrProc, i, CONS_OFFSET, WD ), AllocTemp( WD ), WD ); offsets[ i ] = new_ins->result; PrefixIns( HeadBlock->ins.hd.next, new_ins ); } temp = AllocTemp( WD ), new_ins = MakeMove( offsets[ i ], temp, WD ); PrefixIns( ins, new_ins ); new_ins = MakeBinary( OP_ADD, temp, AllocRegName( DisplayReg() ), temp, WD); PrefixIns( ins, new_ins ); *pop = ScaleIndex( temp, op, place%_4K, op->n.name_class, op->n.size, 0, X_FAKE_BASE ); }
bool GetExpression(std::string line) { bool op = false; int parens = 0; while (line.length() > 0) { //first count the parens for (int i = 0; i < line.length(); i ++) { if (line[i] == '(') { parens++; } else if (line[i] == ')') { parens--; } } if (parens != 0) { error = "parenthesis do not match"; return false; } while (line[0] == ' ' && line[0] != NULL) { if (line.length() == 1) goto Finish; else line = line.substr(1); } if (line[0] == '(') { if (!op) { //first count the parens for (int i = 0; i < line.length(); i ++) { if (line[i] == '(') { parens++; } else if (line[i] == ')') { parens--; if (parens == 0) { if (!GetExpression(line.substr(1).substr(0, i - 1))) return false; line = line.substr(i + 1, line.length() - i); op = true; break; } } } } else { error = "incorrect use of parenthesis"; return false; } } else if (line.find(' ') != string::npos) { if (op) { if (!CheckOp(line.substr(0, line.find_first_of(' ')))) { error = "invalid expression"; return false; } op = false; line = line.substr(line.find_first_of(' '), line.length() - line.find_first_of(' ')); } else { if (!CheckID(line.substr(0, line.find_first_of(' ')))) { error = "invalid expression"; return false; } op = true; line = line.substr(line.find_first_of(' '), line.length() - line.find_first_of(' ')); } } else { if (!op) { if (!CheckID(line)) { error = "invalid expression"; return false; } op = true; line = line.substr(line.length()); } else { error = "cannot end expression in a op"; return false; } } } Finish: return op; }