extern "C" ENCODER_DECLARE_EXPORT char * encoder_imm_reg(Mnemonic m, OpndSize size, int imm, int reg, bool isPhysical, LowOpndRegType type, char * stream) { EncoderBase::Operands args; add_r(args, reg, size); //dst if(m == Mnemonic_IMUL) add_r(args, reg, size); //src CHECK if(m == Mnemonic_SAL || m == Mnemonic_SHR || m == Mnemonic_SHL || m == Mnemonic_SAR || m == Mnemonic_ROR) //fix for shift opcodes add_imm(args, OpndSize_8, imm, true/*is_signed*/); else add_imm(args, size, imm, true/*is_signed*/); char* stream_start = stream; stream = (char *)EncoderBase::encode(stream, m, args); #ifdef PRINT_ENCODER_STREAM printEncoderInst(m, args); decodeThenPrint(stream_start); #endif return stream; }
extern "C" ENCODER_DECLARE_EXPORT char * encoder_imm(Mnemonic m, OpndSize size, int imm, char * stream) { EncoderBase::Operands args; //assert(imm.get_size() == size_32); add_imm(args, size, imm, true/*is_signed*/); char* stream_start = stream; stream = (char *)EncoderBase::encode(stream, m, args); #ifdef PRINT_ENCODER_STREAM printEncoderInst(m, args); decodeThenPrint(stream_start); #endif return stream; }
extern "C" ENCODER_DECLARE_EXPORT char * encoder_update_imm_rm(int imm, char * stream) { Inst decInst; unsigned numBytes = DecoderBase::decode(stream, &decInst); EncoderBase::Operands args; args.add(decInst.operands[0]); add_imm(args, decInst.operands[1].size(), imm, true/*is_signed*/); char* stream_next = (char *)EncoderBase::encode(stream, decInst.mn, args); #ifdef PRINT_ENCODER_STREAM printEncoderInst(decInst.mn, args); decodeThenPrint(stream); #endif return stream_next; }
extern "C" ENCODER_DECLARE_EXPORT char * encoder_imm_mem(Mnemonic m, OpndSize size, int imm, int disp, int base_reg, bool isBasePhysical, char * stream) { EncoderBase::Operands args; add_m(args, base_reg, disp, size); if (m == Mnemonic_SAL || m == Mnemonic_SHR || m == Mnemonic_SHL || m == Mnemonic_SAR || m == Mnemonic_ROR) size = OpndSize_8; add_imm(args, size, imm, true); char* stream_start = stream; stream = (char *)EncoderBase::encode(stream, m, args); #ifdef PRINT_ENCODER_STREAM printEncoderInst(m, args); decodeThenPrint(stream_start); #endif return stream; }
void InterpreterStubs::generate_interpreter_fill_in_tags() { Segment seg(this, code_segment, "Interpreter fill in tags"); Register param_size = tmp0; // must be preserved Register callinfo = tmp1; { bind_local("interpreter_fill_in_tags"); comment("%s: size of parameters", reg_name(tmp0)); comment("%s: call info from call size", reg_name(tmp1)); comment(""); comment("Must preserve lr, %s (method), and %s (parameter size)", reg_name(r0), reg_name(tmp0)); Label loop_entry; // tos_val = r0 must be preserved Register arg_index = tmp2; Register one_reg = tmp3; Register tag_address = JavaStackDirection < 0 ? tmp4 : jsp; mov_imm(one_reg, 1 << CallInfo::format1_tag_start); sub(arg_index, param_size, one, set_CC); report_fatal("shouldn't be called on no arguments", lt); if (JavaStackDirection < 0) { comment("Tag address of last argument"); add(tag_address, jsp, imm(BytesPerWord)); } else { comment("jsp points to tag address of last argument"); } bind(loop_entry); comment("test the bit in the call info"); tst(callinfo, reg_shift(one_reg, lsl, arg_index)); mov(tos_tag, imm(obj_tag), ne); mov(tos_tag, imm(int_tag), eq); if (JavaStackDirection < 0) { str(tos_tag, add_index(tag_address, arg_index, lsl, 3)); } else { str(tos_tag, sub_index(tag_address, arg_index, lsl, 3)); } sub(arg_index, arg_index, one, set_CC); b(loop_entry, ge); mov(pc, reg(locals)); } { Register bit_offset = tmp1; // callinfo not needed Register one_reg = tmp2; Register tag_address = tmp3; Register x1 = tmp4; Register x2 = tmp5; Register index = tos_tag; Label loop; bind_local("interpreter_fill_in_extended_tags"); comment("Total number of tags"); if (HARDWARE_LITTLE_ENDIAN) { ldrh(bit_offset, imm_index3(lr, -2 * BytesPerWord)); } else { ldrh(bit_offset, imm_index3(lr, -2 * BytesPerWord + 2)); } comment("Tag address of first argument"); if (JavaStackDirection < 0) { add(tag_address, jsp, imm_shift(param_size, lsl, 3)); } else { sub(tag_address, jsp, imm_shift(param_size, lsl, 3)); } // tag_address points to the last address of the previous stack add_imm(tag_address, tag_address, JavaFrame::arg_offset_from_sp(-1) + BytesPerWord); comment("Index of last argument"); sub(index, param_size, one); comment("Bit number of first argument"); sub(bit_offset, bit_offset, reg(param_size)); mov(bit_offset, imm_shift(bit_offset, lsl, 2)); add(bit_offset, bit_offset, imm(32 + 32 + 16)); comment("A useful constant"); mov(one_reg, one); bind(loop); comment("Get the bit offset for this argument"); add(x1, bit_offset, imm_shift(index, lsl, 2)); comment("Get the appropriate word"); mov(x2, imm_shift(x1, lsr, 5)); ldr(x2, sub_index(lr, x2, lsl, 2)); comment("Pick out the nybble"); andr(x1, x1, imm(31)); mov(x2, reg_shift(x2, lsr, x1)); andr(x2, x2, imm(15), set_CC); comment("Convert the nybble into a stack type"); sub(x2, x2, one, ne); mov(x2, reg_shift(one_reg, lsl, x2), ne); if (JavaStackDirection < 0) { str(x2, sub_index(tag_address, index, lsl, 3)); } else { str(x2, add_index(tag_address, index, lsl, 3)); } comment("Update the info"); sub(index, index, one, set_CC); b(loop, ge); mov(pc, reg(locals)); } }