Skip to content

Commit 2c38bdd

Browse files
DinoVmeta-codesync[bot]
authored andcommitted
Add custom translation for negate/invert
Summary: Long term it's probably better to do this via a rewrite but this will do for now as this is what Claude produced right before I go on PTO This gets `test_cinderx.test_compiler.test_static.primitives` passing. Reviewed By: kddnewton Differential Revision: D93934607 fbshipit-source-id: a1646f10e87ccefe7ed6cef59e495aaa80bba88b
1 parent 277c4d4 commit 2c38bdd

1 file changed

Lines changed: 61 additions & 7 deletions

File tree

cinderx/Jit/codegen/autogen.cpp

Lines changed: 61 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2278,6 +2278,60 @@ void translateUnreachable(Environ* env, const Instruction* instr) {
22782278
as->udf(0);
22792279
}
22802280

2281+
void translateNegate(Environ* env, const Instruction* instr) {
2282+
a64::Builder* as = env->as;
2283+
2284+
const OperandBase* output =
2285+
instr->getNumOutputs() > 0 ? instr->output() : instr->getInput(0);
2286+
const OperandBase* opnd0 = instr->getInput(0);
2287+
2288+
JIT_CHECK(output->isReg(), "Expected output to be a register");
2289+
2290+
auto output_reg = AT::getGpOutput(output);
2291+
2292+
if (opnd0->isImm()) {
2293+
int64_t constant = opnd0->getConstant();
2294+
as->mov(output_reg, asmjit::Imm(-constant));
2295+
} else if (opnd0->isReg()) {
2296+
as->neg(output_reg, AT::getGpWiden(opnd0));
2297+
} else if (opnd0->isStack()) {
2298+
auto loc = opnd0->getStackSlot().loc;
2299+
auto scratch = AT::getGpWiden(output->dataType(), arch::reg_scratch_0.id());
2300+
auto ptr = arch::ptr_resolve(as, arch::fp, loc, arch::reg_scratch_0);
2301+
as->ldr(scratch, ptr);
2302+
as->neg(output_reg, scratch);
2303+
} else {
2304+
JIT_ABORT("Unsupported operand type for Negate: {}", opnd0->type());
2305+
}
2306+
}
2307+
2308+
void translateInvert(Environ* env, const Instruction* instr) {
2309+
a64::Builder* as = env->as;
2310+
2311+
const OperandBase* output =
2312+
instr->getNumOutputs() > 0 ? instr->output() : instr->getInput(0);
2313+
const OperandBase* opnd0 = instr->getInput(0);
2314+
2315+
JIT_CHECK(output->isReg(), "Expected output to be a register");
2316+
2317+
auto output_reg = AT::getGpOutput(output);
2318+
2319+
if (opnd0->isImm()) {
2320+
uint64_t constant = opnd0->getConstant();
2321+
as->mov(output_reg, asmjit::Imm(~constant));
2322+
} else if (opnd0->isReg()) {
2323+
as->mvn(output_reg, AT::getGpWiden(opnd0));
2324+
} else if (opnd0->isStack()) {
2325+
auto loc = opnd0->getStackSlot().loc;
2326+
auto scratch = AT::getGpWiden(output->dataType(), arch::reg_scratch_0.id());
2327+
auto ptr = arch::ptr_resolve(as, arch::fp, loc, arch::reg_scratch_0);
2328+
as->ldr(scratch, ptr);
2329+
as->mvn(output_reg, scratch);
2330+
} else {
2331+
JIT_ABORT("Unsupported operand type for Invert: {}", opnd0->type());
2332+
}
2333+
}
2334+
22812335
template <typename EmitFn>
22822336
void translateAddSubOp(
22832337
Environ* env,
@@ -2718,16 +2772,16 @@ BEGIN_RULES(Instruction::kDeoptPatchpoint)
27182772
END_RULES
27192773

27202774
BEGIN_RULES(Instruction::kNegate)
2721-
GEN("r", ASM(neg, OP(0), OP(0)))
2722-
GEN("Ri", ASM(mov, OP(0), ImmOperandNegate<OP(1)>))
2723-
GEN("Rr", ASM(neg, OP(0), OP(1)))
2724-
GEN("Rm", ASM(ldr, OP(0), STK(1)), ASM(neg, OP(0), OP(0)))
2775+
GEN("r", CALL_C(translateNegate))
2776+
GEN("Ri", CALL_C(translateNegate))
2777+
GEN("Rr", CALL_C(translateNegate))
2778+
GEN("Rm", CALL_C(translateNegate))
27252779
END_RULES
27262780

27272781
BEGIN_RULES(Instruction::kInvert)
2728-
GEN("Ri", ASM(mov, OP(0), ImmOperandInvert<OP(1)>))
2729-
GEN("Rr", ASM(mvn, OP(0), OP(1)))
2730-
GEN("Rm", ASM(ldr, OP(0), STK(1)), ASM(mvn, OP(0), OP(0)))
2782+
GEN("Ri", CALL_C(translateInvert))
2783+
GEN("Rr", CALL_C(translateInvert))
2784+
GEN("Rm", CALL_C(translateInvert))
27312785
END_RULES
27322786

27332787
BEGIN_RULES(Instruction::kMovZX)

0 commit comments

Comments
 (0)