From a2ebdd74eb2f36e6efa7a482bc11c7b93d97c2c3 Mon Sep 17 00:00:00 2001 From: buzbee Date: Sun, 4 Mar 2012 14:57:06 -0800 Subject: Complete MIPS code generation support With this CL code generation for MIPS is complete (though untested on actual hardware). Core and the boot classpath compile without issue. The primary thrust here was to support expanding of short branch sequences to long form during assembly if the displacement field overflowed. That led to a general cleanup of creation on LIR nodes outside of the normal flow. Also introduced is a README to describe the state of MIPS support, as well as memory barrier handling. Change-Id: I251a2ef8d74bc7183406dce9493464be24a9d7f7 --- src/compiler/codegen/CodegenUtil.cc | 61 ++--- src/compiler/codegen/CompilerCodegen.h | 3 + src/compiler/codegen/GenCommon.cc | 26 +- src/compiler/codegen/arm/Assemble.cc | 52 ++-- src/compiler/codegen/arm/Thumb2/Factory.cc | 60 ++--- src/compiler/codegen/arm/Thumb2/Gen.cc | 8 +- src/compiler/codegen/mips/Assemble.cc | 349 ++++++++++++++++---------- src/compiler/codegen/mips/Mips32/Factory.cc | 45 ++-- src/compiler/codegen/mips/Mips32/Gen.cc | 14 +- src/compiler/codegen/mips/MipsLIR.h | 16 +- src/compiler/codegen/mips/MipsRallocUtil.cc | 2 +- src/compiler/codegen/mips/README.mips | 57 +++++ src/compiler/codegen/mips/mips/ArchVariant.cc | 2 +- 13 files changed, 391 insertions(+), 304 deletions(-) create mode 100644 src/compiler/codegen/mips/README.mips (limited to 'src/compiler/codegen') diff --git a/src/compiler/codegen/CodegenUtil.cc b/src/compiler/codegen/CodegenUtil.cc index 8a38db480f..07eb672eeb 100644 --- a/src/compiler/codegen/CodegenUtil.cc +++ b/src/compiler/codegen/CodegenUtil.cc @@ -410,21 +410,34 @@ void oatCodegenDump(CompilationUnit* cUnit) } } -/* - * The following are building blocks to construct low-level IRs with 0 - 4 - * operands. - */ -LIR* newLIR0(CompilationUnit* cUnit, int opcode) + +LIR* rawLIR(CompilationUnit* cUnit, int dalvikOffset, int opcode, int op0, + int op1, int op2, int op3, LIR* target) { LIR* insn = (LIR* ) oatNew(cUnit, sizeof(LIR), true, kAllocLIR); - DCHECK(isPseudoOpcode(opcode) || (EncodingMap[opcode].flags & NO_OPERAND)); + insn->dalvikOffset = dalvikOffset; insn->opcode = opcode; - setupResourceMasks(insn); - insn->dalvikOffset = cUnit->currentDalvikOffset; + insn->operands[0] = op0; + insn->operands[1] = op1; + insn->operands[2] = op2; + insn->operands[3] = op3; + insn->target = target; + oatSetupResourceMasks(insn); if (opcode == kPseudoTargetLabel) { // Always make labels scheduling barriers insn->defMask = ENCODE_ALL; } + return insn; +} + +/* + * The following are building blocks to construct low-level IRs with 0 - 4 + * operands. + */ +LIR* newLIR0(CompilationUnit* cUnit, int opcode) +{ + DCHECK(isPseudoOpcode(opcode) || (EncodingMap[opcode].flags & NO_OPERAND)); + LIR* insn = rawLIR(cUnit, cUnit->currentDalvikOffset, opcode); oatAppendLIR(cUnit, (LIR*) insn); return insn; } @@ -432,12 +445,8 @@ LIR* newLIR0(CompilationUnit* cUnit, int opcode) LIR* newLIR1(CompilationUnit* cUnit, int opcode, int dest) { - LIR* insn = (LIR* ) oatNew(cUnit, sizeof(LIR), true, kAllocLIR); DCHECK(isPseudoOpcode(opcode) || (EncodingMap[opcode].flags & IS_UNARY_OP)); - insn->opcode = opcode; - insn->operands[0] = dest; - setupResourceMasks(insn); - insn->dalvikOffset = cUnit->currentDalvikOffset; + LIR* insn = rawLIR(cUnit, cUnit->currentDalvikOffset, opcode, dest); oatAppendLIR(cUnit, (LIR*) insn); return insn; } @@ -445,14 +454,9 @@ LIR* newLIR1(CompilationUnit* cUnit, int opcode, LIR* newLIR2(CompilationUnit* cUnit, int opcode, int dest, int src1) { - LIR* insn = (LIR* ) oatNew(cUnit, sizeof(LIR), true, kAllocLIR); DCHECK(isPseudoOpcode(opcode) || (EncodingMap[opcode].flags & IS_BINARY_OP)); - insn->opcode = opcode; - insn->operands[0] = dest; - insn->operands[1] = src1; - setupResourceMasks(insn); - insn->dalvikOffset = cUnit->currentDalvikOffset; + LIR* insn = rawLIR(cUnit, cUnit->currentDalvikOffset, opcode, dest, src1); oatAppendLIR(cUnit, (LIR*) insn); return insn; } @@ -460,18 +464,13 @@ LIR* newLIR2(CompilationUnit* cUnit, int opcode, LIR* newLIR3(CompilationUnit* cUnit, int opcode, int dest, int src1, int src2) { - LIR* insn = (LIR* ) oatNew(cUnit, sizeof(LIR), true, kAllocLIR); DCHECK(isPseudoOpcode(opcode) || (EncodingMap[opcode].flags & IS_TERTIARY_OP)) << (int)opcode << " " << PrettyMethod(cUnit->method_idx, *cUnit->dex_file) << " " << cUnit->currentDalvikOffset; - insn->opcode = opcode; - insn->operands[0] = dest; - insn->operands[1] = src1; - insn->operands[2] = src2; - setupResourceMasks(insn); - insn->dalvikOffset = cUnit->currentDalvikOffset; + LIR* insn = rawLIR(cUnit, cUnit->currentDalvikOffset, opcode, dest, src1, + src2); oatAppendLIR(cUnit, (LIR*) insn); return insn; } @@ -479,16 +478,10 @@ LIR* newLIR3(CompilationUnit* cUnit, int opcode, LIR* newLIR4(CompilationUnit* cUnit, int opcode, int dest, int src1, int src2, int info) { - LIR* insn = (LIR* ) oatNew(cUnit, sizeof(LIR), true, kAllocLIR); DCHECK(isPseudoOpcode(opcode) || (EncodingMap[opcode].flags & IS_QUAD_OP)); - insn->opcode = opcode; - insn->operands[0] = dest; - insn->operands[1] = src1; - insn->operands[2] = src2; - insn->operands[3] = info; - setupResourceMasks(insn); - insn->dalvikOffset = cUnit->currentDalvikOffset; + LIR* insn = rawLIR(cUnit, cUnit->currentDalvikOffset, opcode, dest, src1, + src2, info); oatAppendLIR(cUnit, (LIR*) insn); return insn; } diff --git a/src/compiler/codegen/CompilerCodegen.h b/src/compiler/codegen/CompilerCodegen.h index 26dad8240c..fdcb55557a 100644 --- a/src/compiler/codegen/CompilerCodegen.h +++ b/src/compiler/codegen/CompilerCodegen.h @@ -21,6 +21,9 @@ namespace art { +LIR* rawLIR(CompilationUnit* cUnit, int dalvikOffset, int opcode, int op0 = 0, + int op1 = 0, int op2 = 0, int op3 = 0, LIR* target = NULL); + /* Lower middle-level IR to low-level IR for the whole method */ void oatMethodMIR2LIR(CompilationUnit* cUnit); diff --git a/src/compiler/codegen/GenCommon.cc b/src/compiler/codegen/GenCommon.cc index d0063faf9d..f33b3742a3 100644 --- a/src/compiler/codegen/GenCommon.cc +++ b/src/compiler/codegen/GenCommon.cc @@ -58,10 +58,8 @@ LIR* opUnconditionalBranch(CompilationUnit* cUnit, LIR* target) LIR* genCheck(CompilationUnit* cUnit, ConditionCode cCode, MIR* mir, ThrowKind kind) { - LIR* tgt = (LIR*)oatNew(cUnit, sizeof(LIR), true, kAllocLIR); - tgt->opcode = kPseudoThrowTarget; - tgt->operands[0] = kind; - tgt->operands[1] = mir ? mir->offset : 0; + LIR* tgt = rawLIR(cUnit, 0, kPseudoThrowTarget, kind, + mir ? mir->offset : 0); LIR* branch = opCondBranch(cUnit, cCode, tgt); // Remember branch target - will process later oatInsertGrowableList(cUnit, &cUnit->throwLaunchpads, (intptr_t)tgt); @@ -72,10 +70,7 @@ LIR* genCheck(CompilationUnit* cUnit, ConditionCode cCode, MIR* mir, LIR* genImmedCheck(CompilationUnit* cUnit, ConditionCode cCode, int reg, int immVal, MIR* mir, ThrowKind kind) { - LIR* tgt = (LIR*)oatNew(cUnit, sizeof(LIR), true, kAllocLIR); - tgt->opcode = kPseudoThrowTarget; - tgt->operands[0] = kind; - tgt->operands[1] = mir->offset; + LIR* tgt = rawLIR(cUnit, 0, kPseudoThrowTarget, kind, mir->offset); LIR* branch; if (cCode == kCondAl) { branch = opUnconditionalBranch(cUnit, tgt); @@ -101,12 +96,8 @@ LIR* genNullCheck(CompilationUnit* cUnit, int sReg, int mReg, MIR* mir) LIR* genRegRegCheck(CompilationUnit* cUnit, ConditionCode cCode, int reg1, int reg2, MIR* mir, ThrowKind kind) { - LIR* tgt = (LIR*)oatNew(cUnit, sizeof(LIR), true, kAllocLIR); - tgt->opcode = kPseudoThrowTarget; - tgt->operands[0] = kind; - tgt->operands[1] = mir ? mir->offset : 0; - tgt->operands[2] = reg1; - tgt->operands[3] = reg2; + LIR* tgt = rawLIR(cUnit, 0, kPseudoThrowTarget, kind, + mir ? mir->offset : 0, reg1, reg2); #if defined(TARGET_MIPS) LIR* branch = opCmpBranch(cUnit, cCode, reg1, reg2, tgt); #else @@ -2127,11 +2118,8 @@ void genSuspendTest(CompilationUnit* cUnit, MIR* mir) #endif } LIR* retLab = newLIR0(cUnit, kPseudoTargetLabel); - LIR* target = (LIR*)oatNew(cUnit, sizeof(LIR), true, kAllocLIR); - target->dalvikOffset = cUnit->currentDalvikOffset; - target->opcode = kPseudoSuspendTarget; - target->operands[0] = (intptr_t)retLab; - target->operands[1] = mir->offset; + LIR* target = rawLIR(cUnit, cUnit->currentDalvikOffset, + kPseudoSuspendTarget, (intptr_t)retLab, mir->offset); branch->target = (LIR*)target; oatInsertGrowableList(cUnit, &cUnit->suspendLaunchpads, (intptr_t)target); } diff --git a/src/compiler/codegen/arm/Assemble.cc b/src/compiler/codegen/arm/Assemble.cc index 79a72e74d9..acd2af5535 100644 --- a/src/compiler/codegen/arm/Assemble.cc +++ b/src/compiler/codegen/arm/Assemble.cc @@ -1050,13 +1050,8 @@ AssemblerStatus oatAssembleInstructions(CompilationUnit* cUnit, lir->operands[0] : rLR; // Add new Adr to generate the address - LIR *newAdr = (LIR *)oatNew(cUnit, sizeof(LIR), - true, kAllocLIR); - newAdr->dalvikOffset = lir->dalvikOffset; - newAdr->target = lir->target; - newAdr->opcode = kThumb2Adr; - newAdr->operands[0] = baseReg; - oatSetupResourceMasks(newAdr); + LIR* newAdr = rawLIR(cUnit, lir->dalvikOffset, kThumb2Adr, + baseReg, 0, 0, 0, lir->target); oatInsertLIRBefore((LIR*)lir, (LIR*)newAdr); // Convert to normal load @@ -1083,17 +1078,14 @@ AssemblerStatus oatAssembleInstructions(CompilationUnit* cUnit, intptr_t target = targetLIR->offset; int delta = target - pc; if (delta > 126 || delta < 0) { - /* Convert to cmp rx,#0 / b[eq/ne] tgt pair */ - LIR *newInst = (LIR *)oatNew(cUnit, sizeof(LIR), - true, kAllocLIR); - /* Make new branch instruction and insert after */ - newInst->dalvikOffset = lir->dalvikOffset; - newInst->opcode = kThumbBCond; - newInst->operands[0] = 0; - newInst->operands[1] = (lir->opcode == kThumb2Cbz) ? - kArmCondEq : kArmCondNe; - newInst->target = lir->target; - oatSetupResourceMasks(newInst); + /* + * Convert to cmp rx,#0 / b[eq/ne] tgt pair + * Make new branch instruction and insert after + */ + LIR* newInst = + rawLIR(cUnit, lir->dalvikOffset, kThumbBCond, 0, + (lir->opcode == kThumb2Cbz) ? kArmCondEq : kArmCondNe, + 0, 0, lir->target); oatInsertLIRAfter((LIR *)lir, (LIR *)newInst); /* Convert the cb[n]z to a cmp rx, #0 ] */ lir->opcode = kThumbCmpRI8; @@ -1209,26 +1201,14 @@ AssemblerStatus oatAssembleInstructions(CompilationUnit* cUnit, } else { // convert to ldimm16l, ldimm16h, add tgt, pc, operands[0] LIR *newMov16L = - (LIR *)oatNew(cUnit, sizeof(LIR), true, - kAllocLIR); - newMov16L->dalvikOffset = lir->dalvikOffset; - newMov16L->target = lir->target; - newMov16L->opcode = kThumb2MovImm16LST; - newMov16L->operands[0] = lir->operands[0]; - newMov16L->operands[2] = (intptr_t)lir; - newMov16L->operands[3] = (intptr_t)tabRec; - oatSetupResourceMasks(newMov16L); + rawLIR(cUnit, lir->dalvikOffset, kThumb2MovImm16LST, + lir->operands[0], 0, (intptr_t)lir, (intptr_t)tabRec, + lir->target); oatInsertLIRBefore((LIR*)lir, (LIR*)newMov16L); LIR *newMov16H = - (LIR *)oatNew(cUnit, sizeof(LIR), true, - kAllocLIR); - newMov16H->dalvikOffset = lir->dalvikOffset; - newMov16H->target = lir->target; - newMov16H->opcode = kThumb2MovImm16HST; - newMov16H->operands[0] = lir->operands[0]; - newMov16H->operands[2] = (intptr_t)lir; - newMov16H->operands[3] = (intptr_t)tabRec; - oatSetupResourceMasks(newMov16H); + rawLIR(cUnit, lir->dalvikOffset, kThumb2MovImm16HST, + lir->operands[0], 0, (intptr_t)lir, (intptr_t)tabRec, + lir->target); oatInsertLIRBefore((LIR*)lir, (LIR*)newMov16H); lir->opcode = kThumb2AddRRR; lir->operands[1] = rPC; diff --git a/src/compiler/codegen/arm/Thumb2/Factory.cc b/src/compiler/codegen/arm/Thumb2/Factory.cc index 03a69d5759..b6df8e3ead 100644 --- a/src/compiler/codegen/arm/Thumb2/Factory.cc +++ b/src/compiler/codegen/arm/Thumb2/Factory.cc @@ -68,14 +68,8 @@ LIR* loadFPConstantValue(CompilationUnit* cUnit, int rDest, int value) if (dataTarget == NULL) { dataTarget = addWordData(cUnit, &cUnit->literalList, value); } - LIR* loadPcRel = (LIR* ) oatNew(cUnit, sizeof(LIR), true, - kAllocLIR); - loadPcRel->dalvikOffset = cUnit->currentDalvikOffset; - loadPcRel->opcode = kThumb2Vldrs; - loadPcRel->target = (LIR* ) dataTarget; - loadPcRel->operands[0] = rDest; - loadPcRel->operands[1] = r15pc; - setupResourceMasks(loadPcRel); + LIR* loadPcRel = rawLIR(cUnit, cUnit->currentDalvikOffset, kThumb2Vldrs, + rDest, r15pc, 0, 0, dataTarget); setMemRefType(loadPcRel, true, kLiteral); loadPcRel->aliasInfo = (intptr_t)dataTarget; oatAppendLIR(cUnit, (LIR* ) loadPcRel); @@ -177,13 +171,8 @@ LIR* loadConstantNoClobber(CompilationUnit* cUnit, int rDest, int value) if (dataTarget == NULL) { dataTarget = addWordData(cUnit, &cUnit->literalList, value); } - LIR* loadPcRel = (LIR* ) oatNew(cUnit, sizeof(LIR), true, - kAllocLIR); - loadPcRel->opcode = kThumb2LdrPcRel12; - loadPcRel->target = (LIR* ) dataTarget; - loadPcRel->dalvikOffset = cUnit->currentDalvikOffset; - loadPcRel->operands[0] = rDest; - setupResourceMasks(loadPcRel); + LIR* loadPcRel = rawLIR(cUnit, cUnit->currentDalvikOffset, + kThumb2LdrPcRel12, rDest, 0, 0, 0, dataTarget); setMemRefType(loadPcRel, true, kLiteral); loadPcRel->aliasInfo = (intptr_t)dataTarget; res = loadPcRel; @@ -643,14 +632,9 @@ LIR* loadConstantValueWide(CompilationUnit* cUnit, int rDestLo, int rDestHi, dataTarget = addWideData(cUnit, &cUnit->literalList, valLo, valHi); } - LIR* loadPcRel = (LIR* ) oatNew(cUnit, sizeof(LIR), true, - kAllocLIR); - loadPcRel->dalvikOffset = cUnit->currentDalvikOffset; - loadPcRel->opcode = kThumb2Vldrd; - loadPcRel->target = (LIR* ) dataTarget; - loadPcRel->operands[0] = S2D(rDestLo, rDestHi); - loadPcRel->operands[1] = r15pc; - setupResourceMasks(loadPcRel); + LIR* loadPcRel = rawLIR(cUnit, cUnit->currentDalvikOffset, + kThumb2Vldrd, S2D(rDestLo, rDestHi), + r15pc, 0, 0, dataTarget); setMemRefType(loadPcRel, true, kLiteral); loadPcRel->aliasInfo = (intptr_t)dataTarget; oatAppendLIR(cUnit, (LIR* ) loadPcRel); @@ -1042,28 +1026,22 @@ void loadPair(CompilationUnit* cUnit, int base, int lowReg, int highReg) LIR* fpRegCopy(CompilationUnit* cUnit, int rDest, int rSrc) { - LIR* res = (LIR* ) oatNew(cUnit, sizeof(LIR), true, kAllocLIR); - res->dalvikOffset = cUnit->currentDalvikOffset; - res->operands[0] = rDest; - res->operands[1] = rSrc; - if (rDest == rSrc) { - res->flags.isNop = true; + int opcode; + DCHECK_EQ(DOUBLEREG(rDest), DOUBLEREG(rSrc)); + if (DOUBLEREG(rDest)) { + opcode = kThumb2Vmovd; } else { - DCHECK_EQ(DOUBLEREG(rDest), DOUBLEREG(rSrc)); - if (DOUBLEREG(rDest)) { - res->opcode = kThumb2Vmovd; + if (SINGLEREG(rDest)) { + opcode = SINGLEREG(rSrc) ? kThumb2Vmovs : kThumb2Fmsr; } else { - if (SINGLEREG(rDest)) { - res->opcode = SINGLEREG(rSrc) ? kThumb2Vmovs : kThumb2Fmsr; - } else { - DCHECK(SINGLEREG(rSrc)); - res->opcode = kThumb2Fmrs; - } + DCHECK(SINGLEREG(rSrc)); + opcode = kThumb2Fmrs; } - res->operands[0] = rDest; - res->operands[1] = rSrc; } - setupResourceMasks(res); + LIR* res = rawLIR(cUnit, cUnit->currentDalvikOffset, opcode, rDest, rSrc); + if (rDest == rSrc) { + res->flags.isNop = true; + } return res; } diff --git a/src/compiler/codegen/arm/Thumb2/Gen.cc b/src/compiler/codegen/arm/Thumb2/Gen.cc index cba37b71ce..135199225b 100644 --- a/src/compiler/codegen/arm/Thumb2/Gen.cc +++ b/src/compiler/codegen/arm/Thumb2/Gen.cc @@ -428,8 +428,6 @@ LIR* opRegCopyNoInsert(CompilationUnit* cUnit, int rDest, int rSrc) ArmOpcode opcode; if (FPREG(rDest) || FPREG(rSrc)) return fpRegCopy(cUnit, rDest, rSrc); - res = (LIR* ) oatNew(cUnit, sizeof(LIR), true, kAllocLIR); - res->dalvikOffset = cUnit->currentDalvikOffset; if (LOWREG(rDest) && LOWREG(rSrc)) opcode = kThumbMovRR; else if (!LOWREG(rDest) && !LOWREG(rSrc)) @@ -438,11 +436,7 @@ LIR* opRegCopyNoInsert(CompilationUnit* cUnit, int rDest, int rSrc) opcode = kThumbMovRR_H2L; else opcode = kThumbMovRR_L2H; - - res->operands[0] = rDest; - res->operands[1] = rSrc; - res->opcode = opcode; - setupResourceMasks(res); + res = rawLIR(cUnit, cUnit->currentDalvikOffset, opcode, rDest, rSrc); if (rDest == rSrc) { res->flags.isNop = true; } diff --git a/src/compiler/codegen/mips/Assemble.cc b/src/compiler/codegen/mips/Assemble.cc index 5f215ef6bf..a70d9dafc2 100644 --- a/src/compiler/codegen/mips/Assemble.cc +++ b/src/compiler/codegen/mips/Assemble.cc @@ -106,44 +106,44 @@ MipsEncodingMap EncodingMap[kMipsLast] = { "andi", "!0r,!1r,0x!2h(!2d)", 4), ENCODING_MAP(kMipsB, 0x10000000, kFmtBitBlt, 15, 0, kFmtUnused, -1, -1, kFmtUnused, -1, -1, - kFmtUnused, -1, -1, NO_OPERAND | IS_BRANCH, + kFmtUnused, -1, -1, NO_OPERAND | IS_BRANCH | NEEDS_FIXUP, "b", "!0t!0N", 8), ENCODING_MAP(kMipsBal, 0x04110000, kFmtBitBlt, 15, 0, kFmtUnused, -1, -1, kFmtUnused, -1, -1, - kFmtUnused, -1, -1, NO_OPERAND | IS_BRANCH | REG_DEF_LR, - "bal", "!0t!0N", 8), + kFmtUnused, -1, -1, NO_OPERAND | IS_BRANCH | REG_DEF_LR | + NEEDS_FIXUP, "bal", "!0t!0N", 8), ENCODING_MAP(kMipsBeq, 0x10000000, kFmtBitBlt, 25, 21, kFmtBitBlt, 20, 16, kFmtBitBlt, 15, 0, - kFmtUnused, -1, -1, IS_BINARY_OP | IS_BRANCH | REG_USE01, - "beq", "!0r,!1r,!2t!0N", 8), + kFmtUnused, -1, -1, IS_BINARY_OP | IS_BRANCH | REG_USE01 | + NEEDS_FIXUP, "beq", "!0r,!1r,!2t!0N", 8), ENCODING_MAP(kMipsBeqz, 0x10000000, /* same as beq above with t = $zero */ kFmtBitBlt, 25, 21, kFmtBitBlt, 15, 0, kFmtUnused, -1, -1, - kFmtUnused, -1, -1, IS_UNARY_OP | IS_BRANCH | REG_USE0, - "beqz", "!0r,!1t!0N", 8), + kFmtUnused, -1, -1, IS_UNARY_OP | IS_BRANCH | REG_USE0 | + NEEDS_FIXUP, "beqz", "!0r,!1t!0N", 8), ENCODING_MAP(kMipsBgez, 0x04010000, kFmtBitBlt, 25, 21, kFmtBitBlt, 15, 0, kFmtUnused, -1, -1, - kFmtUnused, -1, -1, IS_UNARY_OP | IS_BRANCH | REG_USE0, - "bgez", "!0r,!1t!0N", 8), + kFmtUnused, -1, -1, IS_UNARY_OP | IS_BRANCH | REG_USE0 | + NEEDS_FIXUP, "bgez", "!0r,!1t!0N", 8), ENCODING_MAP(kMipsBgtz, 0x1C000000, kFmtBitBlt, 25, 21, kFmtBitBlt, 15, 0, kFmtUnused, -1, -1, - kFmtUnused, -1, -1, IS_UNARY_OP | IS_BRANCH | REG_USE0, - "bgtz", "!0r,!1t!0N", 8), + kFmtUnused, -1, -1, IS_UNARY_OP | IS_BRANCH | REG_USE0 | + NEEDS_FIXUP, "bgtz", "!0r,!1t!0N", 8), ENCODING_MAP(kMipsBlez, 0x18000000, kFmtBitBlt, 25, 21, kFmtBitBlt, 15, 0, kFmtUnused, -1, -1, - kFmtUnused, -1, -1, IS_UNARY_OP | IS_BRANCH | REG_USE0, - "blez", "!0r,!1t!0N", 8), + kFmtUnused, -1, -1, IS_UNARY_OP | IS_BRANCH | REG_USE0 | + NEEDS_FIXUP, "blez", "!0r,!1t!0N", 8), ENCODING_MAP(kMipsBltz, 0x04000000, kFmtBitBlt, 25, 21, kFmtBitBlt, 15, 0, kFmtUnused, -1, -1, - kFmtUnused, -1, -1, IS_UNARY_OP | IS_BRANCH | REG_USE0, - "bltz", "!0r,!1t!0N", 8), + kFmtUnused, -1, -1, IS_UNARY_OP | IS_BRANCH | REG_USE0 | + NEEDS_FIXUP, "bltz", "!0r,!1t!0N", 8), ENCODING_MAP(kMipsBnez, 0x14000000, /* same as bne below with t = $zero */ kFmtBitBlt, 25, 21, kFmtBitBlt, 15, 0, kFmtUnused, -1, -1, - kFmtUnused, -1, -1, IS_UNARY_OP | IS_BRANCH | REG_USE0, - "bnez", "!0r,!1t!0N", 8), + kFmtUnused, -1, -1, IS_UNARY_OP | IS_BRANCH | REG_USE0 | + NEEDS_FIXUP, "bnez", "!0r,!1t!0N", 8), ENCODING_MAP(kMipsBne, 0x14000000, kFmtBitBlt, 25, 21, kFmtBitBlt, 20, 16, kFmtBitBlt, 15, 0, - kFmtUnused, -1, -1, IS_BINARY_OP | IS_BRANCH | REG_USE01, - "bne", "!0r,!1r,!2t!0N", 8), + kFmtUnused, -1, -1, IS_BINARY_OP | IS_BRANCH | REG_USE01 | + NEEDS_FIXUP, "bne", "!0r,!1r,!2t!0N", 8), ENCODING_MAP(kMipsDiv, 0x0000001a, kFmtUnused, -1, -1, kFmtUnused, -1, -1, kFmtBitBlt, 25, 21, kFmtBitBlt, 20, 16, IS_QUAD_OP | REG_DEF01 | REG_USE23, @@ -164,8 +164,8 @@ MipsEncodingMap EncodingMap[kMipsLast] = { "jalr", "!0r,!1r!0N", 8), ENCODING_MAP(kMipsJr, 0x00000008, kFmtBitBlt, 25, 21, kFmtUnused, -1, -1, kFmtUnused, -1, -1, - kFmtUnused, -1, -1, IS_UNARY_OP | IS_BRANCH | REG_USE0, - "jr", "!0r!0N", 8), + kFmtUnused, -1, -1, IS_UNARY_OP | IS_BRANCH | REG_USE0 | + NEEDS_FIXUP, "jr", "!0r!0N", 8), ENCODING_MAP(kMipsLahi, 0x3C000000, kFmtBitBlt, 20, 16, kFmtBitBlt, 15, 0, kFmtUnused, -1, -1, kFmtUnused, -1, -1, IS_BINARY_OP | REG_DEF0, @@ -400,26 +400,117 @@ MipsEncodingMap EncodingMap[kMipsLast] = { #endif ENCODING_MAP(kMipsDelta, 0x27e00000, kFmtBitBlt, 20, 16, kFmtBitBlt, 15, 0, kFmtUnused, 15, 0, - kFmtUnused, -1, -1, IS_QUAD_OP | REG_DEF0 | REG_USE_LR, - "addiu", "!0r,r_ra,0x!1h(!1d)", 4), + kFmtUnused, -1, -1, IS_QUAD_OP | REG_DEF0 | REG_USE_LR | + NEEDS_FIXUP, "addiu", "!0r,r_ra,0x!1h(!1d)", 4), ENCODING_MAP(kMipsDeltaHi, 0x3C000000, kFmtBitBlt, 20, 16, kFmtBitBlt, 15, 0, kFmtUnused, -1, -1, - kFmtUnused, -1, -1, IS_QUAD_OP | REG_DEF0, + kFmtUnused, -1, -1, IS_QUAD_OP | REG_DEF0 | NEEDS_FIXUP, "lui", "!0r,0x!1h(!1d)", 4), ENCODING_MAP(kMipsDeltaLo, 0x34000000, kFmtBlt5_2, 16, 21, kFmtBitBlt, 15, 0, kFmtUnused, -1, -1, - kFmtUnused, -1, -1, IS_QUAD_OP | REG_DEF0_USE0, + kFmtUnused, -1, -1, IS_QUAD_OP | REG_DEF0_USE0 | NEEDS_FIXUP, "ori", "!0r,!0r,0x!1h(!1d)", 4), - ENCODING_MAP(kMipsCurrPC, 0x0c000000, + ENCODING_MAP(kMipsCurrPC, 0x04110020, kFmtUnused, -1, -1, kFmtUnused, -1, -1, kFmtUnused, -1, -1, kFmtUnused, -1, -1, NO_OPERAND | IS_BRANCH | REG_DEF_LR, "pc2ra", "; r_ra <- .+8", 4), + ENCODING_MAP(kMipsSync, 0x0000000f, + kFmtBitBlt, 10, 6, kFmtUnused, -1, -1, kFmtUnused, -1, -1, + kFmtUnused, -1, -1, IS_UNARY_OP, + "sync", ";", 4), ENCODING_MAP(kMipsUndefined, 0x64000000, kFmtUnused, -1, -1, kFmtUnused, -1, -1, kFmtUnused, -1, -1, kFmtUnused, -1, -1, NO_OPERAND, "undefined", "", 4), }; + +/* + * Convert a short-form branch to long form. Hopefully, this won't happen + * very often because the PIC sequence is especially unfortunate. + * + * Orig conditional branch + * ----------------------- + * beq rs,rt,target + * + * Long conditional branch + * ----------------------- + * bne rs,rt,hop + * bal .+8 ; r_RA <- anchor + * lui r_AT, ((target-anchor) >> 16) + * anchor: + * ori r_AT, r_AT, ((target-anchor) & 0xffff) + * addu r_AT, r_AT, r_RA + * jr r_AT + * hop: + * + * Orig unconditional branch + * ------------------------- + * b target + * + * Long unconditional branch + * ----------------------- + * bal .+8 ; r_RA <- anchor + * lui r_AT, ((target-anchor) >> 16) + * anchor: + * ori r_AT, r_AT, ((target-anchor) & 0xffff) + * addu r_AT, r_AT, r_RA + * jr r_AT + * + * + * NOTE: An out-of-range bal isn't supported because it should + * never happen with the current PIC model. + */ +void convertShortToLongBranch(CompilationUnit* cUnit, LIR* lir) +{ + // For conditional branches we'll need to reverse the sense + bool unconditional = false; + int opcode = lir->opcode; + int dalvikOffset = lir->dalvikOffset; + switch(opcode) { + case kMipsBal: + LOG(FATAL) << "long branch and link unsupported"; + case kMipsB: + unconditional = true; + break; + case kMipsBeq: opcode = kMipsBne; break; + case kMipsBne: opcode = kMipsBeq; break; + case kMipsBeqz: opcode = kMipsBnez; break; + case kMipsBgez: opcode = kMipsBltz; break; + case kMipsBgtz: opcode = kMipsBlez; break; + case kMipsBlez: opcode = kMipsBgtz; break; + case kMipsBltz: opcode = kMipsBgez; break; + case kMipsBnez: opcode = kMipsBeqz; break; + default: + LOG(FATAL) << "Unexpected branch kind " << (int)opcode; + } + LIR* hopTarget = NULL; + if (!unconditional) { + hopTarget = rawLIR(cUnit, dalvikOffset, kPseudoTargetLabel); + LIR* hopBranch = rawLIR(cUnit, dalvikOffset, opcode, lir->operands[0], + lir->operands[1], 0, 0, hopTarget); + oatInsertLIRBefore(lir, hopBranch); + } + LIR* currPC = rawLIR(cUnit, dalvikOffset, kMipsCurrPC); + oatInsertLIRBefore(lir, currPC); + LIR* anchor = rawLIR(cUnit, dalvikOffset, kPseudoTargetLabel); + LIR* deltaHi = rawLIR(cUnit, dalvikOffset, kMipsDeltaHi, r_AT, 0, + (uintptr_t)anchor, 0, lir->target); + oatInsertLIRBefore(lir, deltaHi); + oatInsertLIRBefore(lir, anchor); + LIR* deltaLo = rawLIR(cUnit, dalvikOffset, kMipsDeltaLo, r_AT, 0, + (uintptr_t)anchor, 0, lir->target); + oatInsertLIRBefore(lir, deltaLo); + LIR* addu = rawLIR(cUnit, dalvikOffset, kMipsAddu, r_AT, r_AT, r_RA); + oatInsertLIRBefore(lir, addu); + LIR* jr = rawLIR(cUnit, dalvikOffset, kMipsJr, r_AT); + oatInsertLIRBefore(lir, jr); + if (!unconditional) { + oatInsertLIRBefore(lir, hopTarget); + } + lir->flags.isNop = true; +} + /* * Assemble the LIR into binary instruction format. Note that we may * discover that pc-relative displacements may not fit the selected @@ -442,108 +533,112 @@ AssemblerStatus oatAssembleInstructions(CompilationUnit *cUnit, continue; } -// TODO: check for lir->flags.pcRelFixup - - if (lir->opcode == kMipsDelta) { - int offset1 = ((LIR*)lir->operands[2])->offset; - SwitchTable *tabRec = (SwitchTable*)lir->operands[3]; - int offset2 = tabRec ? tabRec->offset : lir->target->offset; - int delta = offset2 - offset1; - if ((delta & 0xffff) == delta) { - // Fits - lir->operands[1] = delta; - } else { - // Doesn't fit - must expand to kMipsDelta[Hi|Lo] pair - LIR *newDeltaHi = - (LIR *)oatNew(cUnit, sizeof(LIR), true, - kAllocLIR); - newDeltaHi->dalvikOffset = lir->dalvikOffset; - newDeltaHi->target = lir->target; - newDeltaHi->opcode = kMipsDeltaHi; - newDeltaHi->operands[0] = lir->operands[0]; - newDeltaHi->operands[2] = lir->operands[2]; - newDeltaHi->operands[3] = lir->operands[3]; - oatSetupResourceMasks(newDeltaHi); - oatInsertLIRBefore((LIR*)lir, (LIR*)newDeltaHi); - LIR *newDeltaLo = - (LIR *)oatNew(cUnit, sizeof(LIR), true, - kAllocLIR); - newDeltaLo->dalvikOffset = lir->dalvikOffset; - newDeltaLo->target = lir->target; - newDeltaLo->opcode = kMipsDeltaLo; - newDeltaLo->operands[0] = lir->operands[0]; - newDeltaLo->operands[2] = lir->operands[2]; - newDeltaLo->operands[3] = lir->operands[3]; - oatSetupResourceMasks(newDeltaLo); - oatInsertLIRBefore((LIR*)lir, (LIR*)newDeltaLo); - lir->flags.isNop = true; - res = kRetryAll; - } - } else if (lir->opcode == kMipsDeltaLo) { - int offset1 = ((LIR*)lir->operands[2])->offset; - SwitchTable *tabRec = (SwitchTable*)lir->operands[3]; - int offset2 = tabRec ? tabRec->offset : lir->target->offset; - int delta = offset2 - offset1; - lir->operands[1] = delta & 0xffff; - } else if (lir->opcode == kMipsDeltaHi) { - int offset1 = ((LIR*)lir->operands[2])->offset; - SwitchTable *tabRec = (SwitchTable*)lir->operands[3]; - int offset2 = tabRec ? tabRec->offset : lir->target->offset; - int delta = offset2 - offset1; - lir->operands[1] = (delta >> 16) & 0xffff; - } else if (lir->opcode == kMipsB || lir->opcode == kMipsBal) { - LIR *targetLIR = (LIR *) lir->target; - intptr_t pc = lir->offset + 4; - intptr_t target = targetLIR->offset; - int delta = target - pc; - if (delta & 0x3) { - LOG(FATAL) << "PC-rel offset not multiple of 4: " << delta; - } - if (delta > 131068 || delta < -131069) { - UNIMPLEMENTED(FATAL) << "B out of range, need long sequence: " << delta; - } - lir->operands[0] = delta >> 2; - } else if (lir->opcode >= kMipsBeqz && lir->opcode <= kMipsBnez) { - LIR *targetLIR = (LIR *) lir->target; - intptr_t pc = lir->offset + 4; - intptr_t target = targetLIR->offset; - int delta = target - pc; - if (delta & 0x3) { - LOG(FATAL) << "PC-rel offset not multiple of 4: " << delta; - } - if (delta > 131068 || delta < -131069) { - UNIMPLEMENTED(FATAL) << "B[eq|ne]z needs long sequence: " << delta; - } - lir->operands[1] = delta >> 2; - } else if (lir->opcode == kMipsBeq || lir->opcode == kMipsBne) { - LIR *targetLIR = (LIR *) lir->target; - intptr_t pc = lir->offset + 4; - intptr_t target = targetLIR->offset; - int delta = target - pc; - if (delta & 0x3) { - LOG(FATAL) << "PC-rel offset not multiple of 4: " << delta; - } - if (delta > 131068 || delta < -131069) { - UNIMPLEMENTED(FATAL) << "B[eq|ne] needs long sequence: " << delta; - } - lir->operands[2] = delta >> 2; - } else if (lir->opcode == kMipsJal) { - intptr_t curPC = (startAddr + lir->offset + 4) & ~3; - intptr_t target = lir->operands[0]; - /* ensure PC-region branch can be used */ - DCHECK_EQ((curPC & 0xF0000000), (target & 0xF0000000)); - if (target & 0x3) { - LOG(FATAL) << "Jump target not multiple of 4: " << target; + if (lir->flags.pcRelFixup) { + if (lir->opcode == kMipsDelta) { + /* + * The "Delta" pseudo-ops load the difference between + * two pc-relative locations into a the target register + * found in operands[0]. The delta is determined by + * (label2 - label1), where label1 is a standard + * kPseudoTargetLabel and is stored in operands[2]. + * If operands[3] is null, then label2 is a kPseudoTargetLabel + * and is found in lir->target. If operands[3] is non-NULL, + * then it is a Switch/Data table. + */ + int offset1 = ((LIR*)lir->operands[2])->offset; + SwitchTable *tabRec = (SwitchTable*)lir->operands[3]; + int offset2 = tabRec ? tabRec->offset : lir->target->offset; + int delta = offset2 - offset1; + if ((delta & 0xffff) == delta) { + // Fits + lir->operands[1] = delta; + } else { + // Doesn't fit - must expand to kMipsDelta[Hi|Lo] pair + LIR *newDeltaHi = + rawLIR(cUnit, lir->dalvikOffset, kMipsDeltaHi, + lir->operands[0], 0, lir->operands[2], + lir->operands[3], lir->target); + oatInsertLIRBefore((LIR*)lir, (LIR*)newDeltaHi); + LIR *newDeltaLo = + rawLIR(cUnit, lir->dalvikOffset, kMipsDeltaLo, + lir->operands[0], 0, lir->operands[2], + lir->operands[3], lir->target); + oatInsertLIRBefore((LIR*)lir, (LIR*)newDeltaLo); + lir->flags.isNop = true; + res = kRetryAll; + } + } else if (lir->opcode == kMipsDeltaLo) { + int offset1 = ((LIR*)lir->operands[2])->offset; + SwitchTable *tabRec = (SwitchTable*)lir->operands[3]; + int offset2 = tabRec ? tabRec->offset : lir->target->offset; + int delta = offset2 - offset1; + lir->operands[1] = delta & 0xffff; + } else if (lir->opcode == kMipsDeltaHi) { + int offset1 = ((LIR*)lir->operands[2])->offset; + SwitchTable *tabRec = (SwitchTable*)lir->operands[3]; + int offset2 = tabRec ? tabRec->offset : lir->target->offset; + int delta = offset2 - offset1; + lir->operands[1] = (delta >> 16) & 0xffff; + } else if (lir->opcode == kMipsB || lir->opcode == kMipsBal) { + LIR *targetLIR = (LIR *) lir->target; + intptr_t pc = lir->offset + 4; + intptr_t target = targetLIR->offset; + int delta = target - pc; + if (delta & 0x3) { + LOG(FATAL) << "PC-rel offset not multiple of 4: " << delta; + } + if (delta > 131068 || delta < -131069) { + res = kRetryAll; + convertShortToLongBranch(cUnit, lir); + } else { + lir->operands[0] = delta >> 2; + } + } else if (lir->opcode >= kMipsBeqz && lir->opcode <= kMipsBnez) { + LIR *targetLIR = (LIR *) lir->target; + intptr_t pc = lir->offset + 4; + intptr_t target = targetLIR->offset; + int delta = target - pc; + if (delta & 0x3) { + LOG(FATAL) << "PC-rel offset not multiple of 4: " << delta; + } + if (delta > 131068 || delta < -131069) { + res = kRetryAll; + convertShortToLongBranch(cUnit, lir); + } else { + lir->operands[1] = delta >> 2; + } + } else if (lir->opcode == kMipsBeq || lir->opcode == kMipsBne) { + LIR *targetLIR = (LIR *) lir->target; + intptr_t pc = lir->offset + 4; + intptr_t target = targetLIR->offset; + int delta = target - pc; + if (delta & 0x3) { + LOG(FATAL) << "PC-rel offset not multiple of 4: " << delta; + } + if (delta > 131068 || delta < -131069) { + res = kRetryAll; + convertShortToLongBranch(cUnit, lir); + } else { + lir->operands[2] = delta >> 2; + } + } else if (lir->opcode == kMipsJal) { + intptr_t curPC = (startAddr + lir->offset + 4) & ~3; + intptr_t target = lir->operands[0]; + /* ensure PC-region branch can be used */ + DCHECK_EQ((curPC & 0xF0000000), (target & 0xF0000000)); + if (target & 0x3) { + LOG(FATAL) << "Jump target not multiple of 4: " << target; + } + lir->operands[0] = target >> 2; + } else if (lir->opcode == kMipsLahi) { /* ld address hi (via lui) */ + LIR *targetLIR = (LIR *) lir->target; + intptr_t target = startAddr + targetLIR->offset; + lir->operands[1] = target >> 16; + } else if (lir->opcode == kMipsLalo) { /* ld address lo (via ori) */ + LIR *targetLIR = (LIR *) lir->target; + intptr_t target = startAddr + targetLIR->offset; + lir->operands[2] = lir->operands[2] + target; } - lir->operands[0] = target >> 2; - } else if (lir->opcode == kMipsLahi) { /* load address hi (via lui) */ - LIR *targetLIR = (LIR *) lir->target; - intptr_t target = startAddr + targetLIR->offset; - lir->operands[1] = target >> 16; - } else if (lir->opcode == kMipsLalo) { /* load address lo (via ori) */ - LIR *targetLIR = (LIR *) lir->target; - intptr_t target = startAddr + targetLIR->offset; - lir->operands[2] = lir->operands[2] + target; } /* diff --git a/src/compiler/codegen/mips/Mips32/Factory.cc b/src/compiler/codegen/mips/Mips32/Factory.cc index 105677eef2..ecc01802c0 100644 --- a/src/compiler/codegen/mips/Mips32/Factory.cc +++ b/src/compiler/codegen/mips/Mips32/Factory.cc @@ -28,7 +28,8 @@ static int coreRegs[] = {r_ZERO, r_AT, r_V0, r_V1, r_A0, r_A1, r_A2, r_A3, r_T0, r_T1, r_T2, r_T3, r_T4, r_T5, r_T6, r_T7, r_S0, r_S1, r_S2, r_S3, r_S4, r_S5, r_S6, r_S7, r_T8, r_T9, r_K0, r_K1, r_GP, r_SP, r_FP, r_RA}; -static int reservedRegs[] = {r_ZERO, r_AT, r_S0, r_S1, r_K0, r_K1, r_GP, r_SP, r_RA}; +static int reservedRegs[] = {r_ZERO, r_AT, r_S0, r_S1, r_K0, r_K1, r_GP, r_SP, + r_RA}; static int coreTemps[] = {r_V0, r_V1, r_A0, r_A1, r_A2, r_A3, r_T0, r_T1, r_T2, r_T3, r_T4, r_T5, r_T6, r_T7, r_T8, r_T9}; #ifdef __mips_hard_float @@ -51,33 +52,31 @@ LIR *loadConstant(CompilationUnit *cUnit, int rDest, int value); #ifdef __mips_hard_float LIR *fpRegCopy(CompilationUnit *cUnit, int rDest, int rSrc) { - LIR* res = (LIR *) oatNew(cUnit, sizeof(LIR), true, kAllocLIR); - res->operands[0] = rDest; - res->operands[1] = rSrc; - if (rDest == rSrc) { - res->flags.isNop = true; + int opcode; + /* must be both DOUBLE or both not DOUBLE */ + DCHECK_EQ(DOUBLEREG(rDest),DOUBLEREG(rSrc)); + if (DOUBLEREG(rDest)) { + opcode = kMipsFmovd; } else { - /* must be both DOUBLE or both not DOUBLE */ - DCHECK_EQ(DOUBLEREG(rDest),DOUBLEREG(rSrc)); - if (DOUBLEREG(rDest)) { - res->opcode = kMipsFmovd; - } else { - if (SINGLEREG(rDest)) { - if (SINGLEREG(rSrc)) { - res->opcode = kMipsFmovs; - } else { - /* note the operands are swapped for the mtc1 instr */ - res->opcode = kMipsMtc1; - res->operands[0] = rSrc; - res->operands[1] = rDest; - } + if (SINGLEREG(rDest)) { + if (SINGLEREG(rSrc)) { + opcode = kMipsFmovs; } else { - DCHECK(SINGLEREG(rSrc)); - res->opcode = kMipsMfc1; + /* note the operands are swapped for the mtc1 instr */ + int tOpnd = rSrc; + rSrc = rDest; + rDest = tOpnd; + opcode = kMipsMtc1; } + } else { + DCHECK(SINGLEREG(rSrc)); + opcode = kMipsMfc1; } } - setupResourceMasks(res); + LIR* res = rawLIR(cUnit, cUnit->currentDalvikOffset, opcode, rSrc, rDest); + if (rDest == rSrc) { + res->flags.isNop = true; + } return res; } #endif diff --git a/src/compiler/codegen/mips/Mips32/Gen.cc b/src/compiler/codegen/mips/Mips32/Gen.cc index c975889bed..2bb2f7a560 100644 --- a/src/compiler/codegen/mips/Mips32/Gen.cc +++ b/src/compiler/codegen/mips/Mips32/Gen.cc @@ -389,8 +389,7 @@ LIR* opCmpBranch(CompilationUnit* cUnit, ConditionCode cond, int src1, swapped = true; break; default: - UNIMPLEMENTED(FATAL) << "No support for ConditionCode: " - << (int) cond; + LOG(FATAL) << "No support for ConditionCode: " << (int) cond; return NULL; } if (cmpZero) { @@ -445,19 +444,12 @@ LIR* opCmpImmBranch(CompilationUnit* cUnit, ConditionCode cond, int reg, LIR* opRegCopyNoInsert(CompilationUnit *cUnit, int rDest, int rSrc) { - LIR* res; - MipsOpCode opcode; #ifdef __mips_hard_float if (FPREG(rDest) || FPREG(rSrc)) return fpRegCopy(cUnit, rDest, rSrc); #endif - res = (LIR *) oatNew(cUnit, sizeof(LIR), true, kAllocLIR); - opcode = kMipsMove; - assert(LOWREG(rDest) && LOWREG(rSrc)); - res->operands[0] = rDest; - res->operands[1] = rSrc; - res->opcode = opcode; - setupResourceMasks(res); + LIR* res = rawLIR(cUnit, cUnit->currentDalvikOffset, kMipsMove, + rDest, rSrc); if (rDest == rSrc) { res->flags.isNop = true; } diff --git a/src/compiler/codegen/mips/MipsLIR.h b/src/compiler/codegen/mips/MipsLIR.h index 5034623c2b..18f06ae4b2 100644 --- a/src/compiler/codegen/mips/MipsLIR.h +++ b/src/compiler/codegen/mips/MipsLIR.h @@ -311,9 +311,17 @@ typedef enum MipsShiftEncodings { kMipsRor = 0x3 } MipsShiftEncodings; -// FIXME: Need support for barriers. Adding these defines to allow compile -#define kST 0 -#define kSY 1 +// MIPS sync kinds (Note: support for kinds other than kSYNC0 may not exist) +#define kSYNC0 0x00 +#define kSYNC_WMB 0x04 +#define kSYNC_MB 0x01 +#define kSYNC_ACQUIRE 0x11 +#define kSYNC_RELEASE 0x12 +#define kSYNC_RMB 0x13 + +// TODO: Use smaller hammer when appropriate for target CPU +#define kST kSYNC0 +#define kSY kSYNC0 #define isPseudoOpcode(opCode) ((int)(opCode) < 0) @@ -430,6 +438,7 @@ typedef enum MipsOpCode { kMipsDeltaHi, /* Pseudo for lui t, high16(