Exemple #1
0
STATIC
void GenReadLocal(int regDst, int opSz, int ofs)
{
  int instr = Tr32InstrL;
  if (opSz == -1 || opSz == 1)
  {
    instr = Tr32InstrLB;
  }
  else if (opSz == -2 || opSz == 2)
  {
    instr = Tr32InstrLW;
  }
  GenPrintInstr2Operands(instr, 0,
                         regDst, 0,
                         Tr32OpIndRegBp, ofs);

  if (opSz == -1)
    GenPrintInstr2Operands(Tr32InstrSigxB, 0,
                           regDst, 0,
                           regDst, 0);
  else if (opSz == -2)
    GenPrintInstr2Operands(Tr32InstrSigxW, 0,
                           regDst, 0,
                           regDst, 0);
}
Exemple #2
0
STATIC
void GenReadIndirect(int regDst, int regSrc, int opSz)
{
  int instr = Tr32InstrL;
  if (opSz == -1 || opSz == 1)
  {
    instr = Tr32InstrLB;
  }
  else if (opSz == -2 || opSz == 2)
  {
    instr = Tr32InstrLW;
  }
  GenPrintInstr2Operands(instr, 0,
                         regDst, 0,
                         regSrc + Tr32OpIndReg0, 0);

  if (opSz == -1)
    GenPrintInstr2Operands(Tr32InstrSigxB, 0,
                           regDst, 0,
                           regDst, 0);
  else if (opSz == -2)
    GenPrintInstr2Operands(Tr32InstrSigxW, 0,
                           regDst, 0,
                           regDst, 0);
}
Exemple #3
0
STATIC
void GenExtendRegIfNeeded(int reg, int opSz)
{
  if (opSz == -1)
  {
    GenPrintInstr2Operands(Tr32InstrSigxB, 0,
                           reg, 0,
                           reg, 0);
  }
  else if (opSz == 1)
  {
    GenPrintInstr3Operands(Tr32InstrAnd, 0,
                           reg, 0,
                           reg, 0,
                           Tr32OpConst, 0xFF);
  }
  else if (opSz == -2)
  {
    GenPrintInstr2Operands(Tr32InstrSigxW, 0,
                           reg, 0,
                           reg, 0);
  }
  else if (opSz == 2)
  {
    GenPrintInstr3Operands(Tr32InstrAnd, 0,
                           reg, 0,
                           reg, 0,
                           Tr32OpConst, 0xFFFF);
  }
}
Exemple #4
0
STATIC
void GenReadIdent(int regDst, int opSz, int label)
{
  int instr = Tr32InstrL;
  if (opSz == -1 || opSz == 1)
  {
    instr = Tr32InstrLB;
  }
  else if (opSz == -2 || opSz == 2)
  {
    instr = Tr32InstrLW;
  }
  GenPrintInstr2Operands(instr, 0,
                         regDst, 0,
                         Tr32OpLabel, label);

  if (opSz == -1)
    GenPrintInstr2Operands(Tr32InstrSigxB, 0,
                           regDst, 0,
                           regDst, 0);
  else if (opSz == -2)
    GenPrintInstr2Operands(Tr32InstrSigxW, 0,
                           regDst, 0,
                           regDst, 0);
}
Exemple #5
0
void GenFxnProlog(void)
{
  GenPrintInstr3Operands(MipsInstrSubU, 0,
                         MipsOpRegSp, 0,
                         MipsOpRegSp, 0,
                         MipsOpConst, 8);

  GenPrintInstr2Operands(MipsInstrSW, 0,
                         MipsOpRegRa, 0,
                         MipsOpIndRegSp, 4);

  GenPrintInstr2Operands(MipsInstrSW, 0,
                         MipsOpRegFp, 0,
                         MipsOpIndRegSp, 0);

  GenPrintInstr2Operands(MipsInstrMov, 0,
                         MipsOpRegFp, 0,
                         MipsOpRegSp, 0);

  if (CurFxnParamCntMax)
  {
    int i, cnt = CurFxnParamCntMax;
    if (cnt > 4)
      cnt = 4;
    for (i = 0; i < cnt; i++)
      GenPrintInstr2Operands(MipsInstrSW, 0,
                             MipsOpRegA0 + i, 0,
                             MipsOpIndRegFp, 8 + 4 * i);
  }
}
Exemple #6
0
void GenReadIdent(int regDst, int opSz, int label)
{
  int instr = MipsInstrLW;
  GenPreIdentAccess(label);
  if (opSz == -1)
  {
    instr = MipsInstrLB;
  }
  else if (opSz == 1)
  {
    instr = MipsInstrLBU;
  }
  else if (opSz == -2)
  {
    instr = MipsInstrLH;
  }
  else if (opSz == 2)
  {
    instr = MipsInstrLHU;
  }
  GenPrintInstr2Operands(instr, 0,
                         regDst, 0,
                         MipsOpLabelGpOption, label);
  GenPostIdentAccess();
}
Exemple #7
0
STATIC
void GenJumpIfEqual(int val, int label)
{
  GenPrintInstr2Operands(Tr32InstrIfEq, 0,
                         GenWreg, 0,
                         Tr32OpConst, val);
  GenPrintInstr1Operand(Tr32InstrRJmp, 0,
                        Tr32OpNumLabel, label);
}
Exemple #8
0
void GenJumpIfNotEqual(int val, int label)
{
  GenPrintInstr2Operands(MipsInstrLI, 0,
                         MipsOpRegT1, 0,
                         MipsOpConst, val);
  GenPrintInstr3Operands(MipsInstrBNE, 0,
                         MipsOpRegV0, 0,
                         MipsOpRegT1, 0,
                         MipsOpNumLabel, label);
}
Exemple #9
0
STATIC
void GenJumpIfNotZero(int label)
{
#ifndef NO_ANNOTATIONS
  printf2(" ; JumpIfNotZero\n");
#endif
  GenPrintInstr2Operands(Tr32InstrIfBits, 0,
                         GenWreg, 0,
                         GenWreg, 0);
  GenPrintInstr1Operand(Tr32InstrRJmp, 0,
                        Tr32OpNumLabel, label);
}
Exemple #10
0
STATIC
void GenFxnProlog(void)
{
  GenRegsUsed = 0;

  GenPrintInstr1Operand(Tr32InstrPush, 0,
                        Tr32OpRegBp, 0);

  GenPrintInstr2Operands(Tr32InstrMov, 0,
                         Tr32OpRegBp, 0,
                         Tr32OpRegSp, 0);
}
Exemple #11
0
void GenPushReg(int reg)
{
  if (CanUseTempRegs && TempsUsed < 6)
  {
    GenPrintInstr2Operands(MipsInstrMov, 0,
                           MipsOpRegT2 + TempsUsed, 0,
                           reg, 0);
    TempsUsed++;
    return;
  }

  GenPrintInstr3Operands(MipsInstrSubU, 0,
                         MipsOpRegSp, 0,
                         MipsOpRegSp, 0,
                         MipsOpConst, 4);

  GenPrintInstr2Operands(MipsInstrSW, 0,
                         reg, 0,
                         MipsOpIndRegSp, 0);

  TempsUsed++;
}
Exemple #12
0
void GenFxnEpilog(void)
{
  GenPrintInstr2Operands(MipsInstrMov, 0,
                         MipsOpRegSp, 0,
                         MipsOpRegFp, 0);

  GenPrintInstr2Operands(MipsInstrLW, 0,
                         MipsOpRegFp, 0,
                         MipsOpIndRegSp, 0);

  GenPrintInstr2Operands(MipsInstrLW, 0,
                         MipsOpRegRa, 0,
                         MipsOpIndRegSp, 4);

  GenPrintInstr3Operands(MipsInstrAddU, 0,
                         MipsOpRegSp, 0,
                         MipsOpRegSp, 0,
                         MipsOpConst, 8);

  GenPrintInstr1Operand(MipsInstrJ, 0,
                        MipsOpRegRa, 0);
}
Exemple #13
0
STATIC
void GenFxnEpilog(void)
{
  GenSaveRestoreRegs(0);

  GenPrintInstr2Operands(Tr32InstrMov, 0,
                         Tr32OpRegSp, 0,
                         Tr32OpRegBp, 0);

  GenPrintInstr1Operand(Tr32InstrPop, 0,
                        Tr32OpRegBp, 0);

  GenPrintInstrNoOperand(Tr32InstrRet, 0);
}
Exemple #14
0
void GenWriteIndirect(int regDst, int regSrc, int opSz)
{
  int instr = MipsInstrSW;
  if (opSz == -1 || opSz == 1)
  {
    instr = MipsInstrSB;
  }
  else if (opSz == -2 || opSz == 2)
  {
    instr = MipsInstrSH;
  }
  GenPrintInstr2Operands(instr, 0,
                         regSrc, 0,
                         regDst + MipsOpIndRegZero, 0);
}
Exemple #15
0
void GenWriteLocal(int regSrc, int opSz, int ofs)
{
  int instr = MipsInstrSW;
  if (opSz == -1 || opSz == 1)
  {
    instr = MipsInstrSB;
  }
  else if (opSz == -2 || opSz == 2)
  {
    instr = MipsInstrSH;
  }
  GenPrintInstr2Operands(instr, 0,
                         regSrc, 0,
                         MipsOpIndRegFp, ofs);
}
Exemple #16
0
STATIC
void GenFxnProlog(void)
{
  GenRegsUsed = 0;

  GenPrintInstr1Operand(Tr32InstrPush, 0,
                        Tr32OpRegBp, 0);

  GenPrintInstr2Operands(Tr32InstrMov, 0,
                         Tr32OpRegBp, 0,
                         Tr32OpRegSp, 0);

  fgetpos(OutFile, &GenPrologPos);
  GenWriteFrameSize();
}
Exemple #17
0
STATIC
void GenWriteIdent(int regSrc, int opSz, int label)
{
  int instr = Tr32InstrS;
  if (opSz == -1 || opSz == 1)
  {
    instr = Tr32InstrSB;
  }
  else if (opSz == -2 || opSz == 2)
  {
    instr = Tr32InstrSW;
  }
  GenPrintInstr2Operands(instr, 0,
                         Tr32OpLabel, label,
                         regSrc, 0);
}
Exemple #18
0
STATIC
void GenWriteIndirect(int regDst, int regSrc, int opSz)
{
  int instr = Tr32InstrS;
  if (opSz == -1 || opSz == 1)
  {
    instr = Tr32InstrSB;
  }
  else if (opSz == -2 || opSz == 2)
  {
    instr = Tr32InstrSW;
  }
  GenPrintInstr2Operands(instr, 0,
                         regDst + Tr32OpIndReg0, 0,
                         regSrc, 0);
}
Exemple #19
0
STATIC
void GenWriteLocal(int regSrc, int opSz, int ofs)
{
  int instr = Tr32InstrS;
  if (opSz == -1 || opSz == 1)
  {
    instr = Tr32InstrSB;
  }
  else if (opSz == -2 || opSz == 2)
  {
    instr = Tr32InstrSW;
  }
  GenPrintInstr2Operands(instr, 0,
                         Tr32OpIndRegBp, ofs,
                         regSrc, 0);
}
Exemple #20
0
void GenWriteIdent(int regSrc, int opSz, int label)
{
  int instr = MipsInstrSW;
  GenPreIdentAccess(label);
  if (opSz == -1 || opSz == 1)
  {
    instr = MipsInstrSB;
  }
  else if (opSz == -2 || opSz == 2)
  {
    instr = MipsInstrSH;
  }
  GenPrintInstr2Operands(instr, 0,
                         regSrc, 0,
                         MipsOpLabelGpOption, label);
  GenPostIdentAccess();
}
Exemple #21
0
int GenPopReg(int reg)
{
  TempsUsed--;

  if (CanUseTempRegs && TempsUsed < 6)
  {
    return MipsOpRegT2 + TempsUsed;
  }

  GenPrintInstr2Operands(MipsInstrLW, 0,
                         reg, 0,
                         MipsOpIndRegSp, 0);

  GenPrintInstr3Operands(MipsInstrAddU, 0,
                         MipsOpRegSp, 0,
                         MipsOpRegSp, 0,
                         MipsOpConst, 4);
  return reg;
}
Exemple #22
0
void GenReadIndirect(int regDst, int regSrc, int opSz)
{
  int instr = MipsInstrLW;
  if (opSz == -1)
  {
    instr = MipsInstrLB;
  }
  else if (opSz == 1)
  {
    instr = MipsInstrLBU;
  }
  else if (opSz == -2)
  {
    instr = MipsInstrLH;
  }
  else if (opSz == 2)
  {
    instr = MipsInstrLHU;
  }
  GenPrintInstr2Operands(instr, 0,
                         regDst, 0,
                         regSrc + MipsOpIndRegZero, 0);
}
Exemple #23
0
void GenReadLocal(int regDst, int opSz, int ofs)
{
  int instr = MipsInstrLW;
  if (opSz == -1)
  {
    instr = MipsInstrLB;
  }
  else if (opSz == 1)
  {
    instr = MipsInstrLBU;
  }
  else if (opSz == -2)
  {
    instr = MipsInstrLH;
  }
  else if (opSz == 2)
  {
    instr = MipsInstrLHU;
  }
  GenPrintInstr2Operands(instr, 0,
                         regDst, 0,
                         MipsOpIndRegFp, ofs);
}
Exemple #24
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;
    }
  }
}