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); }
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); }
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); } }
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); }
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); } }
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(); }
STATIC void GenJumpIfEqual(int val, int label) { GenPrintInstr2Operands(Tr32InstrIfEq, 0, GenWreg, 0, Tr32OpConst, val); GenPrintInstr1Operand(Tr32InstrRJmp, 0, Tr32OpNumLabel, label); }
void GenJumpIfNotEqual(int val, int label) { GenPrintInstr2Operands(MipsInstrLI, 0, MipsOpRegT1, 0, MipsOpConst, val); GenPrintInstr3Operands(MipsInstrBNE, 0, MipsOpRegV0, 0, MipsOpRegT1, 0, MipsOpNumLabel, label); }
STATIC void GenJumpIfNotZero(int label) { #ifndef NO_ANNOTATIONS printf2(" ; JumpIfNotZero\n"); #endif GenPrintInstr2Operands(Tr32InstrIfBits, 0, GenWreg, 0, GenWreg, 0); GenPrintInstr1Operand(Tr32InstrRJmp, 0, Tr32OpNumLabel, label); }
STATIC void GenFxnProlog(void) { GenRegsUsed = 0; GenPrintInstr1Operand(Tr32InstrPush, 0, Tr32OpRegBp, 0); GenPrintInstr2Operands(Tr32InstrMov, 0, Tr32OpRegBp, 0, Tr32OpRegSp, 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++; }
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); }
STATIC void GenFxnEpilog(void) { GenSaveRestoreRegs(0); GenPrintInstr2Operands(Tr32InstrMov, 0, Tr32OpRegSp, 0, Tr32OpRegBp, 0); GenPrintInstr1Operand(Tr32InstrPop, 0, Tr32OpRegBp, 0); GenPrintInstrNoOperand(Tr32InstrRet, 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); }
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); }
STATIC void GenFxnProlog(void) { GenRegsUsed = 0; GenPrintInstr1Operand(Tr32InstrPush, 0, Tr32OpRegBp, 0); GenPrintInstr2Operands(Tr32InstrMov, 0, Tr32OpRegBp, 0, Tr32OpRegSp, 0); fgetpos(OutFile, &GenPrologPos); GenWriteFrameSize(); }
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); }
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); }
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); }
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(); }
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; }
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); }
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); }
// 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; } } }