Exemple #1
0
void GenIncDecIndirect(int regDst, int regSrc, int opSz, int tok)
{
  int instr = MipsInstrAddU;

  if (tok != tokInc)
    instr = MipsInstrSubU;

  GenReadIndirect(regDst, regSrc, opSz);
  GenPrintInstr3Operands(instr, 0,
                         regDst, 0,
                         regDst, 0,
                         MipsOpConst, 1);
  GenWriteIndirect(regSrc, regDst, opSz);
  GenExtendRegIfNeeded(regDst, opSz);
}
Exemple #2
0
void GenIncDecLocal(int regDst, int opSz, int ofs, int tok)
{
  int instr = MipsInstrAddU;

  if (tok != tokInc)
    instr = MipsInstrSubU;

  GenReadLocal(regDst, opSz, ofs);
  GenPrintInstr3Operands(instr, 0,
                         regDst, 0,
                         regDst, 0,
                         MipsOpConst, 1);
  GenWriteLocal(regDst, opSz, ofs);
  GenExtendRegIfNeeded(regDst, opSz);
}
Exemple #3
0
STATIC
void GenIncDecIdent(int regDst, int opSz, int label, int tok)
{
  int instr = Tr32InstrAdd;

  if (tok != tokInc)
    instr = Tr32InstrSub;

  GenReadIdent(regDst, opSz, label);
  GenPrintInstr3Operands(instr, 0,
                         regDst, 0,
                         regDst, 0,
                         Tr32OpConst, 1);
  GenWriteIdent(regDst, opSz, label);
  GenExtendRegIfNeeded(regDst, opSz);
}
Exemple #4
0
void GenPostIncDecIdent(int regDst, int opSz, int label, int tok)
{
  int instr = MipsInstrAddU;

  if (tok != tokPostInc)
    instr = MipsInstrSubU;

  GenReadIdent(regDst, opSz, label);
  GenPrintInstr3Operands(instr, 0,
                         regDst, 0,
                         regDst, 0,
                         MipsOpConst, 1);
  GenWriteIdent(regDst, opSz, label);
  GenPrintInstr3Operands(instr, 0,
                         regDst, 0,
                         regDst, 0,
                         MipsOpConst, -1);
  GenExtendRegIfNeeded(regDst, opSz);
}
Exemple #5
0
STATIC
void GenPostIncDecIndirect(int regDst, int regSrc, int opSz, int tok)
{
  int instr = Tr32InstrAdd;

  if (tok != tokPostInc)
    instr = Tr32InstrSub;

  GenReadIndirect(regDst, regSrc, opSz);
  GenPrintInstr3Operands(instr, 0,
                         regDst, 0,
                         regDst, 0,
                         Tr32OpConst, 1);
  GenWriteIndirect(regSrc, regDst, opSz);
  GenPrintInstr3Operands(instr, 0,
                         regDst, 0,
                         regDst, 0,
                         Tr32OpConst, -1);
  GenExtendRegIfNeeded(regDst, opSz);
}
Exemple #6
0
STATIC
void GenPostIncDecLocal(int regDst, int opSz, int ofs, int tok)
{
  int instr = Tr32InstrAdd;

  if (tok != tokPostInc)
    instr = Tr32InstrSub;

  GenReadLocal(regDst, opSz, ofs);
  GenPrintInstr3Operands(instr, 0,
                         regDst, 0,
                         regDst, 0,
                         Tr32OpConst, 1);
  GenWriteLocal(regDst, opSz, ofs);
  GenPrintInstr3Operands(instr, 0,
                         regDst, 0,
                         regDst, 0,
                         Tr32OpConst, -1);
  GenExtendRegIfNeeded(regDst, opSz);
}
Exemple #7
0
// Original, primitive stack-based code generator
// DONE: test 32-bit code generation
void GenExpr0(void)
{
  int i;
  int gotUnary = 0;
  int maxCallDepth = 0;
  int callDepth = 0;
  int paramOfs = 0;

  for (i = 0; i < sp; i++)
    if (stack[i][0] == '(')
    {
      if (++callDepth > maxCallDepth)
        maxCallDepth = callDepth;
    }
    else if (stack[i][0] == ')')
    {
      callDepth--;
    }

  CanUseTempRegs = maxCallDepth == 0;
  TempsUsed = 0;

  for (i = 0; i < sp; i++)
  {
    int tok = stack[i][0];
    int v = stack[i][1];

#ifndef NO_ANNOTATIONS
    switch (tok)
    {
    case tokNumInt: printf2(" # %d\n", truncInt(v)); break;
    case tokNumUint: printf2(" # %uu\n", truncUint(v)); break;
    case tokIdent: printf2(" # %s\n", IdentTable + v); break;
    case tokLocalOfs: printf2(" # local ofs\n"); break;
    case ')': printf2(" # ) fxn call\n"); break;
    case tokUnaryStar: printf2(" # * (read dereference)\n"); break;
    case '=': printf2(" # = (write dereference)\n"); break;
    case tokShortCirc: printf2(" # short-circuit "); break;
    case tokGoto: printf2(" # sh-circ-goto "); break;
    case tokLogAnd: printf2(" # short-circuit && target\n"); break;
    case tokLogOr: printf2(" # short-circuit || target\n"); break;
    case tokIf: case tokIfNot: break;
    default: printf2(" # %s\n", GetTokenName(tok)); break;
    }
#endif

    switch (tok)
    {
    case tokNumInt:
    case tokNumUint:
      if (!(i + 1 < sp && (strchr("+-&^|", stack[i + 1][0]) ||
                           stack[i + 1][0] == tokLShift ||
                           stack[i + 1][0] == tokRShift ||
                           stack[i + 1][0] == tokURShift)))
      {
        if (gotUnary)
          GenPushReg(MipsOpRegV0);

        GenPrintInstr2Operands(MipsInstrLI, 0,
                               MipsOpRegV0, 0,
                               MipsOpConst, v);
      }
      gotUnary = 1;
      break;

    case tokIdent:
      if (gotUnary)
        GenPushReg(MipsOpRegV0);
      if (!(i + 1 < sp && (stack[i + 1][0] == ')' ||
                           stack[i + 1][0] == tokUnaryStar ||
                           stack[i + 1][0] == tokInc ||
                           stack[i + 1][0] == tokDec ||
                           stack[i + 1][0] == tokPostInc ||
                           stack[i + 1][0] == tokPostDec)))
      {
        GenPrintInstr2Operands(MipsInstrLA, 0,
                               MipsOpRegV0, 0,
                               MipsOpLabel, v);
      }
      gotUnary = 1;
      break;

    case tokLocalOfs:
      if (gotUnary)
        GenPushReg(MipsOpRegV0);
      if (!(i + 1 < sp && (stack[i + 1][0] == tokUnaryStar ||
                           stack[i + 1][0] == tokInc ||
                           stack[i + 1][0] == tokDec ||
                           stack[i + 1][0] == tokPostInc ||
                           stack[i + 1][0] == tokPostDec)))
      {
        GenPrintInstr3Operands(MipsInstrAddU, 0,
                               MipsOpRegV0, 0,
                               MipsOpRegFp, 0,
                               MipsOpConst, v);
      }
      gotUnary = 1;
      break;

    case '(':
      if (gotUnary)
        GenPushReg(MipsOpRegV0);
      gotUnary = 0;
      if (v < 16)
        GenLocalAlloc(16 - v);
      paramOfs = v - 4;
      break;

    case ',':
      if (maxCallDepth == 1)
      {
        if (paramOfs == 16)
        {
          GenPushReg(MipsOpRegV0);
          gotUnary = 0;
        }
        if (paramOfs >= 0 && paramOfs <= 12)
        {
          GenPrintInstr2Operands(MipsInstrMov, 0,
                                 MipsOpRegA0 + paramOfs / 4, 0,
                                 MipsOpRegV0, 0);
          gotUnary = 0;
        }
        paramOfs -= 4;
      }
      break;

    case ')':
      if (maxCallDepth != 1)
      {
        if (v >= 4)
          GenPrintInstr2Operands(MipsInstrLW, 0,
                                 MipsOpRegA0, 0,
                                 MipsOpIndRegSp, 0);
        if (v >= 8)
          GenPrintInstr2Operands(MipsInstrLW, 0,
                                 MipsOpRegA1, 0,
                                 MipsOpIndRegSp, 4);
        if (v >= 12)
          GenPrintInstr2Operands(MipsInstrLW, 0,
                                 MipsOpRegA2, 0,
                                 MipsOpIndRegSp, 8);
        if (v >= 16)
          GenPrintInstr2Operands(MipsInstrLW, 0,
                                 MipsOpRegA3, 0,
                                 MipsOpIndRegSp, 12);
      }
      else
      {
        int vv = v;
        if (vv > 16)
          vv = 16;
        if (vv)
          GenLocalAlloc(vv);
      }
      if (stack[i - 1][0] == tokIdent)
      {
        GenPrintInstr1Operand(MipsInstrJAL, 0,
                              MipsOpLabel, stack[i - 1][1]);
      }
      else
      {
        GenPrintInstr1Operand(MipsInstrJAL, 0,
                              MipsOpRegV0, 0);
      }
      if (v < 16)
        v = 16;
      GenLocalAlloc(-v);
      break;

    case tokUnaryStar:
      if (stack[i - 1][0] == tokIdent)
        GenReadIdent(MipsOpRegV0, v, stack[i - 1][1]);
      else if (stack[i - 1][0] == tokLocalOfs)
        GenReadLocal(MipsOpRegV0, v, stack[i - 1][1]);
      else
        GenReadIndirect(MipsOpRegV0, MipsOpRegV0, v);
      break;

    case tokUnaryPlus:
      break;
    case '~':
      GenPrintInstr3Operands(MipsInstrNor, 0,
                             MipsOpRegV0, 0,
                             MipsOpRegV0, 0,
                             MipsOpRegV0, 0);
      break;
    case tokUnaryMinus:
      GenPrintInstr3Operands(MipsInstrSubU, 0,
                             MipsOpRegV0, 0,
                             MipsOpRegZero, 0,
                             MipsOpRegV0, 0);
      break;

    case '+':
    case '-':
    case '*':
    case '&':
    case '^':
    case '|':
    case tokLShift:
    case tokRShift:
    case tokURShift:
      if ((stack[i - 1][0] == tokNumInt || stack[i - 1][0] == tokNumUint) && tok != '*')
      {
        int instr = GenGetBinaryOperatorInstr(tok);
        GenPrintInstr3Operands(instr, 0,
                               MipsOpRegV0, 0,
                               MipsOpRegV0, 0,
                               MipsOpConst, stack[i - 1][1]);
      }
      else
      {
        int instr = GenGetBinaryOperatorInstr(tok);
        int reg = GenPopReg(MipsOpRegT0);
        GenPrintInstr3Operands(instr, 0,
                               MipsOpRegV0, 0,
                               reg, 0,
                               MipsOpRegV0, 0);
      }
      break;

    case '/':
    case tokUDiv:
    case '%':
    case tokUMod:
      {
        int reg = GenPopReg(MipsOpRegT0);
        if (tok == '/' || tok == '%')
          GenPrintInstr2Operands(MipsInstrDiv, 0,
                                 reg, 0,
                                 MipsOpRegV0, 0);
        else
          GenPrintInstr2Operands(MipsInstrDivU, 0,
                                 reg, 0,
                                 MipsOpRegV0, 0);
        if (tok == '%' || tok == tokUMod)
          GenPrintInstr1Operand(MipsInstrMfHi, 0,
                                MipsOpRegV0, 0);
        else
          GenPrintInstr1Operand(MipsInstrMfLo, 0,
                                MipsOpRegV0, 0);
      }
      break;

    case tokInc:
    case tokDec:
      if (stack[i - 1][0] == tokIdent)
      {
        GenIncDecIdent(MipsOpRegV0, v, stack[i - 1][1], tok);
      }
      else if (stack[i - 1][0] == tokLocalOfs)
      {
        GenIncDecLocal(MipsOpRegV0, v, stack[i - 1][1], tok);
      }
      else
      {
        GenPrintInstr2Operands(MipsInstrMov, 0,
                               MipsOpRegT0, 0,
                               MipsOpRegV0, 0);
        GenIncDecIndirect(MipsOpRegV0, MipsOpRegT0, v, tok);
      }
      break;
    case tokPostInc:
    case tokPostDec:
      if (stack[i - 1][0] == tokIdent)
      {
        GenPostIncDecIdent(MipsOpRegV0, v, stack[i - 1][1], tok);
      }
      else if (stack[i - 1][0] == tokLocalOfs)
      {
        GenPostIncDecLocal(MipsOpRegV0, v, stack[i - 1][1], tok);
      }
      else
      {
        GenPrintInstr2Operands(MipsInstrMov, 0,
                               MipsOpRegT0, 0,
                               MipsOpRegV0, 0);
        GenPostIncDecIndirect(MipsOpRegV0, MipsOpRegT0, v, tok);
      }
      break;

    case tokPostAdd:
    case tokPostSub:
      {
        int instr = GenGetBinaryOperatorInstr(tok);
        int reg = GenPopReg(MipsOpRegT0);
        GenPrintInstr2Operands(MipsInstrMov, 0,
                               MipsOpRegT1, 0,
                               MipsOpRegV0, 0);

        GenReadIndirect(MipsOpRegV0, reg, v);
        GenPrintInstr3Operands(instr, 0,
                               MipsOpRegT1, 0,
                               MipsOpRegT1, 0,
                               MipsOpRegV0, 0);
        GenWriteIndirect(reg, MipsOpRegT1, v);
      }
      break;

    case tokAssignAdd:
    case tokAssignSub:
    case tokAssignMul:
    case tokAssignAnd:
    case tokAssignXor:
    case tokAssignOr:
    case tokAssignLSh:
    case tokAssignRSh:
    case tokAssignURSh:
      {
        int instr = GenGetBinaryOperatorInstr(tok);
        int reg = GenPopReg(MipsOpRegT0);
        GenPrintInstr2Operands(MipsInstrMov, 0,
                               MipsOpRegT1, 0,
                               MipsOpRegV0, 0);

        GenReadIndirect(MipsOpRegV0, reg, v);
        GenPrintInstr3Operands(instr, 0,
                               MipsOpRegV0, 0,
                               MipsOpRegV0, 0,
                               MipsOpRegT1, 0);
        GenWriteIndirect(reg, MipsOpRegV0, v);

        GenExtendRegIfNeeded(MipsOpRegV0, v);
      }
      break;

    case tokAssignDiv:
    case tokAssignUDiv:
    case tokAssignMod:
    case tokAssignUMod:
      {
        int reg = GenPopReg(MipsOpRegT0);

        GenReadIndirect(MipsOpRegT1, reg, v);
        if (tok == tokAssignDiv || tok == tokAssignMod)
          GenPrintInstr2Operands(MipsInstrDiv, 0,
                                 MipsOpRegT1, 0,
                                 MipsOpRegV0, 0);
        else
          GenPrintInstr2Operands(MipsInstrDivU, 0,
                                 MipsOpRegT1, 0,
                                 MipsOpRegV0, 0);
        if (tok == tokAssignMod || tok == tokAssignUMod)
          GenPrintInstr1Operand(MipsInstrMfHi, 0,
                                MipsOpRegV0, 0);
        else
          GenPrintInstr1Operand(MipsInstrMfLo, 0,
                                MipsOpRegV0, 0);
        GenWriteIndirect(reg, MipsOpRegV0, v);

        GenExtendRegIfNeeded(MipsOpRegV0, v);
      }
      break;

    case '=':
      {
        int reg = GenPopReg(MipsOpRegT0);
        GenWriteIndirect(reg, MipsOpRegV0, v);
        GenExtendRegIfNeeded(MipsOpRegV0, v);
      }
      break;

/*
  i = il < ir;  // i = slt(il, ir);
  i = il <= ir; // i = slt(ir, il) ^ 1;
  i = il > ir;  // i = slt(ir, il);
  i = il >= ir; // i = slt(il, ir) ^ 1;
  i = il == ir; // i = sltu(il ^ ir, 1);
  i = il != ir; // i = sltu(0, il ^ ir);
*/
    case '<':
      {
        int reg = GenPopReg(MipsOpRegT0);
        GenPrintInstr3Operands(MipsInstrSLT, 0,
                               MipsOpRegV0, 0,
                               reg, 0,
                               MipsOpRegV0, 0);
      }
      break;
    case tokULess:
      {
        int reg = GenPopReg(MipsOpRegT0);
        GenPrintInstr3Operands(MipsInstrSLTU, 0,
                               MipsOpRegV0, 0,
                               reg, 0,
                               MipsOpRegV0, 0);
      }
      break;
    case '>':
      {
        int reg = GenPopReg(MipsOpRegT0);
        GenPrintInstr3Operands(MipsInstrSLT, 0,
                               MipsOpRegV0, 0,
                               MipsOpRegV0, 0,
                               reg, 0);
      }
      break;
    case tokUGreater:
      {
        int reg = GenPopReg(MipsOpRegT0);
        GenPrintInstr3Operands(MipsInstrSLTU, 0,
                               MipsOpRegV0, 0,
                               MipsOpRegV0, 0,
                               reg, 0);
      }
      break;
    case tokLEQ:
      {
        int reg = GenPopReg(MipsOpRegT0);
        GenPrintInstr3Operands(MipsInstrSLT, 0,
                               MipsOpRegV0, 0,
                               MipsOpRegV0, 0,
                               reg, 0);
        GenPrintInstr3Operands(MipsInstrXor, 0,
                               MipsOpRegV0, 0,
                               MipsOpRegV0, 0,
                               MipsOpConst, 1);
      }
      break;
    case tokULEQ:
      {
        int reg = GenPopReg(MipsOpRegT0);
        GenPrintInstr3Operands(MipsInstrSLTU, 0,
                               MipsOpRegV0, 0,
                               MipsOpRegV0, 0,
                               reg, 0);
        GenPrintInstr3Operands(MipsInstrXor, 0,
                               MipsOpRegV0, 0,
                               MipsOpRegV0, 0,
                               MipsOpConst, 1);
      }
      break;
    case tokGEQ:
      {
        int reg = GenPopReg(MipsOpRegT0);
        GenPrintInstr3Operands(MipsInstrSLT, 0,
                               MipsOpRegV0, 0,
                               reg, 0,
                               MipsOpRegV0, 0);
        GenPrintInstr3Operands(MipsInstrXor, 0,
                               MipsOpRegV0, 0,
                               MipsOpRegV0, 0,
                               MipsOpConst, 1);
      }
      break;
    case tokUGEQ:
      {
        int reg = GenPopReg(MipsOpRegT0);
        GenPrintInstr3Operands(MipsInstrSLTU, 0,
                               MipsOpRegV0, 0,
                               reg, 0,
                               MipsOpRegV0, 0);
        GenPrintInstr3Operands(MipsInstrXor, 0,
                               MipsOpRegV0, 0,
                               MipsOpRegV0, 0,
                               MipsOpConst, 1);
      }
      break;
    case tokEQ:
      {
        int reg = GenPopReg(MipsOpRegT0);
        GenPrintInstr3Operands(MipsInstrXor, 0,
                               MipsOpRegV0, 0,
                               reg, 0,
                               MipsOpRegV0, 0);
        GenPrintInstr3Operands(MipsInstrSLTU, 0,
                               MipsOpRegV0, 0,
                               MipsOpRegV0, 0,
                               MipsOpConst, 1);
      }
      break;
    case tokNEQ:
      {
        int reg = GenPopReg(MipsOpRegT0);
        GenPrintInstr3Operands(MipsInstrXor, 0,
                               MipsOpRegV0, 0,
                               reg, 0,
                               MipsOpRegV0, 0);
        GenPrintInstr3Operands(MipsInstrSLTU, 0,
                               MipsOpRegV0, 0,
                               MipsOpRegZero, 0,
                               MipsOpRegV0, 0);
      }
      break;

    case tok_Bool:
      GenPrintInstr3Operands(MipsInstrSLTU, 0,
                             MipsOpRegV0, 0,
                             MipsOpRegZero, 0,
                             MipsOpRegV0, 0);
      break;

    case tokSChar:
      GenPrintInstr3Operands(MipsInstrSLL, 0,
                             MipsOpRegV0, 0,
                             MipsOpRegV0, 0,
                             MipsOpConst, 24);
      GenPrintInstr3Operands(MipsInstrSRA, 0,
                             MipsOpRegV0, 0,
                             MipsOpRegV0, 0,
                             MipsOpConst, 24);
      break;
    case tokUChar:
      GenPrintInstr3Operands(MipsInstrAnd, 0,
                             MipsOpRegV0, 0,
                             MipsOpRegV0, 0,
                             MipsOpConst, 0xFF);
      break;
    case tokShort:
      GenPrintInstr3Operands(MipsInstrSLL, 0,
                             MipsOpRegV0, 0,
                             MipsOpRegV0, 0,
                             MipsOpConst, 16);
      GenPrintInstr3Operands(MipsInstrSRA, 0,
                             MipsOpRegV0, 0,
                             MipsOpRegV0, 0,
                             MipsOpConst, 16);
      break;
    case tokUShort:
      GenPrintInstr3Operands(MipsInstrAnd, 0,
                             MipsOpRegV0, 0,
                             MipsOpRegV0, 0,
                             MipsOpConst, 0xFFFF);
      break;

    case tokShortCirc:
#ifndef NO_ANNOTATIONS
      if (v >= 0)
        printf2("&&\n");
      else
        printf2("||\n");
#endif
      if (v >= 0)
        GenJumpIfZero(v); // &&
      else
        GenJumpIfNotZero(-v); // ||
      gotUnary = 0;
      break;
    case tokGoto:
#ifndef NO_ANNOTATIONS
      printf2("goto\n");
#endif
      GenJumpUncond(v);
      gotUnary = 0;
      break;
    case tokLogAnd:
    case tokLogOr:
      GenNumLabel(v);
      break;

    case tokVoid:
      gotUnary = 0;
      break;

    case tokComma:
      break;

    case tokIf:
      GenJumpIfNotZero(stack[i][1]);
      break;
    case tokIfNot:
      GenJumpIfZero(stack[i][1]);
      break;

    default:
      //error("Error: Internal Error: GenExpr0(): unexpected token %s\n", GetTokenName(tok));
      errorInternal(102);
      break;
    }
  }
}