@@ -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+
22812335template <typename EmitFn>
22822336void translateAddSubOp (
22832337 Environ* env,
@@ -2718,16 +2772,16 @@ BEGIN_RULES(Instruction::kDeoptPatchpoint)
27182772END_RULES
27192773
27202774BEGIN_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 ))
27252779END_RULES
27262780
27272781BEGIN_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 ))
27312785END_RULES
27322786
27332787BEGIN_RULES (Instruction::kMovZX )
0 commit comments