36 #define DEBUG_NAME "compiler2/x86_64"
62 ABORT_MSG(
"Type Not supported!",
"get_OperandSize_from_Type: " << type);
91 && fits_into<s1>(imm->
get_Int())) ||
93 && fits_into<s1>(imm->
get_Long())) ) {
174 ABORT_MSG(
"x86_64: get operand size not support",
189 else if (dst == src1) {
199 bool imm_sign_extended =
false;
204 opcode = (
alu_id * 0x08) + 0x00;
209 opcode = (
alu_id * 0x08) + 0x03;
212 opcode = (
alu_id * 0x08) + 0x02;
217 opcode = (
alu_id * 0x08) + 0x01;
222 opcode = (
alu_id * 0x08) + 0x03;
234 imm_sign_extended =
true;
246 ABORT_MSG(
this <<
": Operand(s) not supported",
247 "dst: " << dst <<
" src: " << src <<
" op_size: "
252 InstructionEncoding::emit(CM,opcode,
get_op_size(),src,dst,0,op_reg,0,
false,
true,imm_sign_extended);
256 assert(length >= 0 && length <= 9);
257 unsigned mcodeptr = 0;
262 code[mcodeptr++] = 0x90;
265 code[mcodeptr++] = 0x66;
266 code[mcodeptr++] = 0x90;
269 code[mcodeptr++] = 0x0f;
270 code[mcodeptr++] = 0x1f;
271 code[mcodeptr++] = 0x00;
274 code[mcodeptr++] = 0x0f;
275 code[mcodeptr++] = 0x1f;
276 code[mcodeptr++] = 0x40;
277 code[mcodeptr++] = 0x00;
280 code[mcodeptr++] = 0x0f;
281 code[mcodeptr++] = 0x1f;
282 code[mcodeptr++] = 0x44;
283 code[mcodeptr++] = 0x00;
284 code[mcodeptr++] = 0x00;
287 code[mcodeptr++] = 0x66;
288 code[mcodeptr++] = 0x0f;
289 code[mcodeptr++] = 0x1f;
290 code[mcodeptr++] = 0x44;
291 code[mcodeptr++] = 0x00;
292 code[mcodeptr++] = 0x00;
295 code[mcodeptr++] = 0x0f;
296 code[mcodeptr++] = 0x1f;
297 code[mcodeptr++] = 0x80;
298 code[mcodeptr++] = 0x00;
299 code[mcodeptr++] = 0x00;
300 code[mcodeptr++] = 0x00;
301 code[mcodeptr++] = 0x00;
304 code[mcodeptr++] = 0x0f;
305 code[mcodeptr++] = 0x1f;
306 code[mcodeptr++] = 0x84;
307 code[mcodeptr++] = 0x00;
308 code[mcodeptr++] = 0x00;
309 code[mcodeptr++] = 0x00;
310 code[mcodeptr++] = 0x00;
311 code[mcodeptr++] = 0x00;
314 code[mcodeptr++] = 0x66;
315 code[mcodeptr++] = 0x0f;
316 code[mcodeptr++] = 0x1f;
317 code[mcodeptr++] = 0x84;
318 code[mcodeptr++] = 0x00;
319 code[mcodeptr++] = 0x00;
320 code[mcodeptr++] = 0x00;
321 code[mcodeptr++] = 0x00;
322 code[mcodeptr++] = 0x00;
395 bool encode_dst =
true;
438 ABORT_MSG(
this <<
": Operand(s) not supported",
439 "dst: " << dst <<
" src: " << src <<
" op_size: "
479 code[0] =
get_rex(dst_reg, src_reg);
494 code[0] =
get_rex(dst_reg, src_reg);
509 code[0] =
get_rex(dst_reg,src_reg);
520 ABORT_MSG(
"x86_64 sext cast not supported",
"from " <<
from <<
"bits to "
549 ABORT_MSG(
this <<
": Operand(s) not supported",
556 LOG2(
this <<
" offset: " << offset <<
" data index: " <<
data_index.idx <<
" CF end index "
568 CF[3] =
u1(0xff & (offset >> 0));
569 CF[4] =
u1(0xff & (offset >> 8));
570 CF[5] =
u1(0xff & (offset >> 16));
571 CF[6] =
u1(0xff & (offset >> 24));
576 ABORT_MSG(
this <<
": Operand(s) not supported",
582 case 0:
return OS <<
"then";
583 case 1:
return OS <<
"else";
584 default: assert(0);
break;
596 code[2] = (0x7 & src_reg->
get_index()) << 3 | 0x4;
600 code[4] =
u1( 0xff & (
trap >> (8 * 0)));
601 code[5] =
u1( 0xff & (
trap >> (8 * 1)));
602 code[6] =
u1( 0xff & (
trap >> (8 * 2)));
603 code[7] =
u1( 0xff & (
trap >> (8 * 3)));
606 InstructionEncoding::imm_op<u2>(CM, 0x0f80 +
cond.
code, offset);
634 LOG2(
"X86_64CondJumpInst: target not yet known (" <<
this <<
" to "
635 << *MBB <<
")" <<
nl);
646 ABORT_MSG(
"x86_64 ERROR",
"CondJump offset 0 oO!");
649 LOG2(
"found offset of " << *MBB <<
": " << offset <<
nl);
652 InstructionEncoding::imm_op<u2>(CM, 0x0f80 +
cond.
code, offset);
662 InstructionEncoding::imm_op<u2>(CF, 0x0f80 +
cond.
code, offset);
670 InstructionEncoding::reg2reg<u2>(CM, 0x0faf, dst_reg, src_reg);
683 if (fits_into<s1>(immval)){
684 InstructionEncoding::reg2imm_modrm<u1,s1>(CM, 0x6b, dst_reg, src_reg, immval);
686 InstructionEncoding::reg2imm_modrm<u1,s4>(CM, 0x69, dst_reg, src_reg, immval);
706 LOG2(
"emit_jump codefragment offset: " <<
hex << offset <<
nl);
708 code[1] =
u1( 0xff & (offset >> (8 * 0)));
709 code[2] =
u1( 0xff & (offset >> (8 * 1)));
710 code[3] =
u1( 0xff & (offset >> (8 * 2)));
711 code[4] =
u1( 0xff & (offset >> (8 * 3)));
720 LOG2(
"emit_Jump: target not yet known (" <<
this <<
" to "
721 << *MBB <<
")" <<
nl);
731 LOG2(
"emit_Jump: jump to the next instruction -> can be omitted ("
732 <<
this <<
" to " << *MBB <<
")" <<
nl);
736 emit_jump(CF,offset);
743 LOG2(
"JumpInst:link BI: " << *MBB <<
" idx: " << idx.idx <<
" CF begin: "
748 emit_jump(CF,offset);
755 WARNING_MSG(
"Not yet implemented",
"No support for indirect jump yet.");
819 ABORT_MSG(
this <<
": Operand(s) not supported",
820 "dst: " << dst <<
" src: " << src <<
" op_size: "
843 ABORT_MSG(
this <<
": Operand(s) not supported",
844 "dst: " << dst <<
" src: " << src <<
" op_size: "
871 ABORT_MSG(
this <<
": Operand(s) not supported",
872 "dst: " << dst <<
" src: " << src <<
" op_size: "
924 InstructionEncoding::imm<double>(DF,imm->
get_Double());
931 InstructionEncoding::imm<int64_t>(DF,imm->
get_Long());
944 InstructionEncoding::imm<float>(DF,imm->
get_Float());
951 InstructionEncoding::imm<int32_t>(DF,imm->
get_Int());
968 LOG2(
this <<
" offset: " << offset <<
" data index: " <<
data_index.idx <<
" CF end index "
977 CF[i++] =
u1(0xff & (offset >> 0));
978 CF[i++] =
u1(0xff & (offset >> 8));
979 CF[i++] =
u1(0xff & (offset >> 16));
980 CF[
i ] =
u1(0xff & (offset >> 24));
1008 code[1] =
get_rex(dst_reg,src_reg);
1016 ABORT_MSG(
this <<
": Operand(s) not supported",
1017 "dst: " << dst <<
" src: " << src <<
" op_size: "
1043 code[1] =
get_rex(dst_reg,src_reg);
1051 ABORT_MSG(
this <<
": Operand(s) not supported",
1052 "dst: " << dst <<
" src: " << src <<
" op_size: "
1078 code[1] =
get_rex(dst_reg,src_reg);
1086 ABORT_MSG(
this <<
": Operand(s) not supported",
1087 "dst: " << dst <<
" src: " << src <<
" op_size: "
1113 code[1] =
get_rex(dst_reg,src_reg);
1121 ABORT_MSG(
this <<
": Operand(s) not supported",
1122 "dst: " << dst <<
" src: " << src <<
" op_size: "
1182 ABORT_MSG(
this <<
": Operand size for FLD not supported",
1190 if (fits_into<s1>(index)) {
1192 code += (
u1) 0xff & (index >> 0x00);
1195 code += (
u1) 0xff & (index >> 0x00);
1196 code += (
u1) 0xff & (index >> 0x08);
1197 code += (
u1) 0xff & (index >> 0x10);
1198 code += (
u1) 0xff & (index >> 0x18);
1229 ABORT_MSG(
this <<
": Operand size for FSTP not supported",
1237 if (fits_into<s1>(index)) {
1239 code += (
u1) 0xff & (index >> 0x00);
1242 code += (
u1) 0xff & (index >> 0x00);
1243 code += (
u1) 0xff & (index >> 0x08);
1244 code += (
u1) 0xff & (index >> 0x10);
1245 code += (
u1) 0xff & (index >> 0x18);
virtual void emit(CodeMemory *CM) const
emit machine code
virtual void emit(CodeMemory *CM) const
emit machine code
jlong jlong jlong jlong jint jmethodID jint slot
virtual void emit(CodeMemory *CM) const
emit machine code
virtual void link(CodeFragment &CF) const
link machine code
X86_64Register * cast_to< X86_64Register >(Register *reg)
CodeFragment get_CodeFragment(std::size_t size)
get a code fragment
ConstTag< DataSegmentType, float, FloatID > DSFloat
virtual void emit(CodeMemory *CM) const
emit machine code
void set_target(MachineBasicBlock *target)
CodeFragment get_aligned_CodeFragment(std::size_t size)
get an aligned code fragment
GPInstruction::OperandSize get_OperandSize_from_Type(const Type::TypeID type)
#define WARNING_MSG(EXPR_SHORT, EXPR_LONG)
virtual void emit(CodeMemory *CM) const
emit machine code
virtual void emit(CodeMemory *CM) const
emit machine code
OperandID get_OperandID() const
virtual void emit(CodeMemory *CM) const
emit machine code
GPInstruction::OperandSize from
virtual void emit(CodeMemory *CM) const
emit machine code
u1 get_modrm_reg2reg(X86_64Register *reg, X86_64Register *rm)
virtual void emit(CodeMemory *CM) const
emit machine code
A basic block of (scheduled) machine instructions.
virtual void emit(CodeMemory *CM) const
emit machine code
virtual void link(CodeFragment &CF) const
link machine code
u1 get_modrm_1reg(u1 reg, X86_64Register *rm)
virtual void emit(CodeMemory *CM) const
emit machine code
MachineOperandDesc result
virtual void emit(CodeMemory *CM) const
emit machine code
void add_CodeSegmentBuilder(CodeMemory *CM, const CodeSegmentBuilder &CSB)
virtual void emit(CodeMemory *CM) const
emit machine code
virtual void emit(CodeMemory *CM) const
emit machine code
MachineBasicBlock * successor_back() const
virtual void link(CodeFragment &CF) const
link machine code
Extension of the ModR/M reg field.
std::size_t size() const
get size
virtual void emit(CodeMemory *CM) const
emit machine code
virtual void emit(CodeMemory *CM) const
emit machine code
u1 get_rex(X86_64Register *reg, X86_64Register *rm=NULL, bool opsiz64=true)
virtual void emit(CodeMemory *CM) const
emit machine code
ConstTag< DataSegmentType, int32_t, IntID > DSInt
virtual uintptr_t get_mpc() const =0
get the absolute position in code segment
const CodeSegment & get_CodeSegment() const
get CodeSegment
virtual OStream & print_successor_label(OStream &OS, std::size_t index) const
print successor label
Extension of the SIB index field.
static bool is_invalid(IdxTy idx)
is invalid index
virtual void emit(CodeMemory *CM) const
emit machine code
GPInstruction::OpEncoding get_OpEncoding(MachineOperand *src1, MachineOperand *src2, GPInstruction::OperandSize op_size)
void require_linking(const MachineInstruction *, CodeFragment CF)
Add a MachineInstruction that require linking.
MachineBasicBlock * successor_front() const
virtual void emit(CodeMemory *CM) const
emit machine code
GPInstruction::OperandSize get_operand_size_from_Type(Type::TypeID type)
virtual void emit(CodeMemory *CM) const
emit machine code
virtual void emit(CodeMemory *CM) const
emit machine code
s4 get_offset(CodeSegment::IdxTy to, CodeSegment::IdxTy from) const
GPInstruction::OperandSize to
DataSegment::IdxTy data_index
virtual void emit(CodeMemory *CM) const
emit machine code
OperandSize get_op_size() const
GPRegister RBP("RBP", 0x5, false, 0x5 *8, 8)
virtual void emit(CodeMemory *CM) const
emit machine code
Segment< Tag, RefCategory > * get_Segment() const
Get containing segment.
virtual void emit(CodeMemory *CM) const
emit machine code
std::size_t op_size() const
0 = Operand size determined by CS.D 1 = 64 Bit Operand Size
CodeMemory * get_CodeMemory() const
Get containing CodeMemory.
void emit_nop(CodeFragment code, int length)
IdxTy get_end() const
Get the index of the first element after the reference.
Simple stream class for formatted output.
StackSlot * cast_to< StackSlot >(MachineOperand *op)
virtual void reposition(intptr_t base)=0
reposition to another base
unsigned get_index() const
std::size_t size() const
size of the reference
virtual void link(CodeFragment &CF) const
link machine code
PointerTag< CodeSegmentType, const MachineBasicBlock, LabelID > CSLabel
virtual void emit(CodeMemory *CM) const
emit machine code
IdxTy insert_tag(SegmentTag< Tag > *tag, IdxTy o)
insert tag
Immediate * cast_to< Immediate >(MachineOperand *op)
GPInstruction::OperandSize to
virtual void emit(CodeMemory *CM) const
emit machine code
static void emit(CodeMemory *CM, u1 primary_opcode, GPInstruction::OperandSize op_size, MachineOperand *src, MachineOperand *dst, u1 secondary_opcode=0, u1 op_reg=0, u1 prefix=0, bool prefix_0f=false, bool encode_dst=true, bool imm_sign_extended=false)
virtual void emit(CodeMemory *CM) const
emit machine code
GPInstruction::OperandSize from
ConstTag< DataSegmentType, int64_t, LongID > DSLong
bool is_VoidOperand() const
DataSegment::IdxTy data_index
IdxTy get_index(Tag2 tag) const
get the index of a tag
MachineOperandDesc & index
bool aquivalent(const MachineOperand &MO) const
u1 get_modrm_u1(u1 mod, u1 reg, u1 rm)
JumpInst jump
jump to the else target
virtual void emit(CodeMemory *CM) const
emit machine code
virtual void emit(CodeMemory *CM) const
emit machine code
Type::TypeID get_type() const
virtual void emit(CodeMemory *CM) const
This must be implemented by subclasses.
Operands that can be directly used by the machine (register, memory, stackslot)
virtual void link(CodeFragment &CF) const
link machine code
const MachineOperandDesc & get_result() const
Extension of the ModR/M r/m field, SIB base field, or Opcode reg field.
virtual void emit(CodeMemory *CM) const
emit machine code
virtual void emit(CodeMemory *CM) const
emit machine code
virtual void emit(CodeMemory *CM) const
emit machine code
ConstTag< DataSegmentType, double, DoubleID > DSDouble
IdxTy get_begin() const
Get the index of the first element.
GPInstruction::OperandSize to
virtual void emit(CodeMemory *CM) const
emit machine code
#define ABORT_MSG(EXPR_SHORT, EXPR_LONG)
virtual void emit(CodeMemory *CM) const
emit machine code
const char const void jint length
Ref get_Ref(std::size_t t)
get a new reference to the segment
FPUStackRegister * fpureg
GPInstruction::OperandSize from
MachineOperandDesc & base
const DataSegment & get_DataSegment() const
get DataSegment
virtual void emit(CodeMemory *CM) const
emit machine code
virtual void emit(CodeMemory *CM) const
emit machine code
virtual void emit(CodeMemory *CM) const
emit machine code