Ejemplo n.º 1
0
// EXPR1 && EXPR2
// DND
void CodeGen::visitCAExprAnd(CAExprAnd *caexprand)
{
  curExpr.push(maxExpr++);
  int reg1 = allocRegs(1);  

  string andAfter = getLabel(curScope, "and", maxExpr, "after");


  caexprand->conditionalandexpression_->accept(this);
  emitCmd("MOV", reg1, 0);
  emitCmd("MOV", 0, "#0");
  emitCmd("CMP", reg1, 0);
  emitCmd("BEQ", andAfter);
  emitCmd("MOV", 0, "#1");


  caexprand->equalityexpression_->accept(this);
  emitCmd("MOV", reg1, 0);
  emitCmd("MOV", 0, "#0");
  emitCmd("CMP", reg1, 0);

  emitCmd("MOVNE", 0, "#1");

  emitLabel(andAfter);

  curExpr.pop();
  freeRegs(1);  
}
Ejemplo n.º 2
0
/* Make register r available by making the opdesc that uses it (if
 * any) use a different register.  Call getFreeRegnum to get a new
 * register (which in turn may cause spilling of some other register).
 * If 'op' is the opdesc that uses r, we need to MODIFY op since it is
 * still being used.  Note that op could be a regop, dispop, or
 * indexop (in which case r could be either op->reg or op->reg2), but
 * in all cases we want to output "movl r, newreg" and update op to
 * use newreg instead of r.
 */
void makeAvailable(regnum r, int line) 
{
    opdesc *op = regTab[r].op;
    // if r is free, return, else:
    if (op == NULL) return;

    outputDebugS("making reg %s available", regname[r]);
    assert(!regTab[r].locked);

     // lock the opdesc's register(s) while getting a new regnum
    lock(op);
    regnum newr = getFreeRegnum();
    unlock(op);

    // output a movl instruction and the current opdesc
    outputCmd("movl", line);
    outputReg(r);
    
    // mark the opdesc's register(s) (r and perhaps another) as free
    freeRegs(op);

    // change the opdesc to the new register and output that
    if (op->reg == r) op->reg = newr;
    if (op->reg2 == r) op->reg2 = newr;
    outputReg(newr);

    // update regTab to reflect that the new register now belongs to the opdesc
    regTab[r].op = NULL;
    regTab[newr].op = op;
}
Ejemplo n.º 3
0
/* Free op's register(s) by spilling it into a memtemp.  Update op to reflect
 * the change.  If op is a dispop or indexop, need to 'movl' it into the
 * register it occupies (parameter r) before spilling.
 * If availMemTemps is not NULL, reuse first available displacement, else
 * increase localsize to get a new displacement.
 */
void spill(opdesc *op, regnum r) 
{

    int disp;
    // first, compute the correct displacement, and output one of:
    if(availMemTemps == NULL){
        currentfundesc->fun.localsize += INTSIZE;
        disp = LOCAL_OFFS - currentfundesc->fun.localsize;
        outputDebugN("creating new memtemp at disp %d", disp);
    } else {
        memTemp *memFree = availMemTemps;
        disp = availMemTemps->disp;
        if (availMemTemps->next == NULL) availMemTemps = NULL;
        else availMemTemps = availMemTemps->next;
        free(memFree);
        outputDebugN("reusing memtemp at disp %d", disp);
    }

    // if memory location (dispop or indexop), need to move it into reg first:
    //   output movl instruction and op, then mark op's register(s) as free,
    //   then change op into register r and output that

    if (isMemloc(op)) {
        outputCmd("movl", 0);
        outputOp(op);
        freeRegs(op);
        op->type = regop;
        op->reg = r;
        op->isTemp = 0;        
        outputOp(op);
    }

    // now we are ready for the actual spilling:
    // output movl instruction and op, then mark op's register as free
    // then use makeDispOp to change op into a temporary displacement off ebp
    // and output op

    assert(op->type == regop);
    outputCmd("movl", 0);
    outputOp(op);
    freeRegs(op);
    makeDispOp(op, disp, TRUE);
    op->reg = ebp;
    outputOp(op);

}
Ejemplo n.º 4
0
//EXPR1 - EXPR2
// DND
void CodeGen::visitAddExprSub(AddExprSub *addexprsub)
{
  int reg1 = allocRegs(1);
  addexprsub->additiveexpression_->accept(this);
  emitCmd("MOV", reg1, 0);

  addexprsub->multiplicativeexpression_->accept(this);
  emitCmd("SUB", 0, reg1, 0);
  freeRegs(1);
}
Ejemplo n.º 5
0
// EXPR1 + EXPR2
// DND
void CodeGen::visitAddExprAdd(AddExprAdd *addexpradd)
{
  int reg1 = allocRegs(1);
  addexpradd->additiveexpression_->accept(this);
  emitCmd("MOV", reg1, 0);

  addexpradd->multiplicativeexpression_->accept(this);
  emitCmd("ADD", 0, reg1, 0);
  freeRegs(1);
}
Ejemplo n.º 6
0
// EXPR1 / EXPR2
// DND -- T18, T26, T31
// Uses *SIGNED* division
void CodeGen::visitMulExprDiv(MulExprDiv *mulexprdiv)
{
  int reg1 = allocRegs(1);
  mulexprdiv->multiplicativeexpression_->accept(this);
  emitCmd("MOV", reg1, 0);

  mulexprdiv->unaryexpression_->accept(this);
  emitCmd("SDIV", 0, reg1, 0);
  freeRegs(1);
}
Ejemplo n.º 7
0
// EXPR1 * EXPR2
// DND
void CodeGen::visitMulExprMul(MulExprMul *mulexprmul)
{
  int reg1 = allocRegs(1);
  mulexprmul->multiplicativeexpression_->accept(this);
  emitCmd("MOV", reg1, 0);

  mulexprmul->unaryexpression_->accept(this);
  emitCmd("MUL", 0, reg1, 0);
  freeRegs(1);
}
Ejemplo n.º 8
0
// !EXPR
// DND
void CodeGen::visitUnExprNeg(UnExprNeg *unexprneg)
{
  unexprneg->unaryexpression_->accept(this);
  int reg1 = allocRegs(1);

  // BOOKMARK
  emitCmd("MOV", reg1, 0);
  emitCmd("MOV", 0, "#0");
  emitCmd("CMP", reg1, 0);
  emitCmd("MOVNE", 0, "#1");

  freeRegs(1);
}
Ejemplo n.º 9
0
/* compute the address of a memory location */
opdesc *computeAddress(opdesc *op, int line)
{
    // similar to forceToReg, except uses "leal" instead of "movl"
    freeRegs(op); /* free regs used by op so we can reuse them */
    opdesc *newop = newRegOp(getFreeRegnum());

    outputCmd("leal", line);
    outputOp(op);
    outputOp(newop);
    freeMemtemp(op);
    free(op);

    return newop;
}
Ejemplo n.º 10
0
// EXPR1 != EXPR2
// DND
void CodeGen::visitEqExprNE(EqExprNE *eqexprne)
{
  curExpr.push(maxExpr++);
  int reg1 = allocRegs(1);  
  eqexprne->equalityexpression_->accept(this);
  emitCmd("MOV", reg1, 0);

  eqexprne->relationalexpression_->accept(this);
  emitCmd("CMP", reg1, 0);

  emitCmd("MOVNE", 0, "#1");
  emitCmd("MOVEQ", 0, "#0");

  curExpr.pop();
  freeRegs(1);  
}
Ejemplo n.º 11
0
// EXPR1 >= EXPR2
// DND
void CodeGen::visitRelExprGE(RelExprGE *relexprge)
{
  curExpr.push(maxExpr++);
  int reg1 = allocRegs(1);  
  relexprge->relationalexpression_->accept(this);
  emitCmd("MOV", reg1, 0);

  relexprge->additiveexpression_->accept(this);
  emitCmd("CMP", reg1, 0);

  emitCmd("MOVGE", 0, "#1");
  emitCmd("MOVLT", 0, "#0");

  curExpr.pop();
  freeRegs(1);  
}
Ejemplo n.º 12
0
/* Force an operand to a register.  If it is a register already, just
 * return it. Otherwise, allocate a new register, output code to move
 * the operand to the register, free the old operand, and return the
 * new register.  In order to allow the operand's register(s) to be
 * reused, call freeRegs(op) before allocating a new register, but
 * don't call freeOp(op) until the end.
 */
opdesc *forceToReg(opdesc *op, int line)
{
    // use getFreeRegnum and newRegOp

    if (op->type == regop) return op;
    freeRegs(op); /* free regs used by op so we can reuse them */
    opdesc *newop = newRegOp(getFreeRegnum());

    outputCmd("movl", line);
    outputOp(op);
    outputOp(newop);
    freeMemtemp(op);
    free(op);

    return newop;
}
Ejemplo n.º 13
0
// EXPR1 % EXPR2
// TODO -- LONGFILES AND T26
void CodeGen::visitMulExprMod(MulExprMod *mulexprmod)
{
  int reg1 = allocRegs(1);
  int reg2 = allocRegs(1);

  mulexprmod->multiplicativeexpression_->accept(this);
  emitCmd("MOV", reg1, 0);  // A is in reg1


  mulexprmod->unaryexpression_->accept(this);
  emitCmd("MOV", reg2, 0);  // B is in reg2
  emitCmd("SDIV", 0, reg1, 0);
  // q(a,b) is in r0
  emitCmd("MUL", 0, reg2, 0);
  emitCmd("SUB", 0, reg1, 0);

  freeRegs(2);
}
Ejemplo n.º 14
0
// EXPR1 || EXPR2
// DND
void CodeGen::visitCOExprOr(COExprOr *coexpror)
{
  curExpr.push(maxExpr++);
  int reg1 = allocRegs(1);  
  coexpror->conditionalorexpression_->accept(this);
  emitCmd("MOV", reg1, 0);

  coexpror->conditionalandexpression_->accept(this);

  // result of this add can only be 0, 1, or 2. 
  emitCmd("ADD", 0, reg1, 0);
  emitCmd("CMP", 0, "#0");

  // if it's not 0, move 1 in there just in case it's 2.
  emitCmd("MOVGT", 0, "#1");

  curExpr.pop();
  freeRegs(1);  
}
Ejemplo n.º 15
0
void freeOp(opdesc *op) 
{
    freeRegs(op);
    freeMemtemp(op);
    free(op);
}