Commit 38d18dda authored by qinsoon's avatar qinsoon
Browse files

start using 8/16/32 bits registers

1. compiler knows all the registers
2. but only 64bits register is a color (for reg alloc)
3. backend records the length of GPR for each operand during instruction
selection
4. after reg alloc, when replacing temp with a color, find corresponding
GPR for the length recorded before
parent 5c0bdb9f
...@@ -36,11 +36,11 @@ lazy_static! { ...@@ -36,11 +36,11 @@ lazy_static! {
}; };
} }
pub const MACHINE_ID_START : usize = 0; pub const MACHINE_ID_START : usize = 0;
pub const MACHINE_ID_END : usize = 100; pub const MACHINE_ID_END : usize = 200;
pub const INTERNAL_ID_START: usize = 101; pub const INTERNAL_ID_START: usize = 201;
pub const INTERNAL_ID_END : usize = 200; pub const INTERNAL_ID_END : usize = 500;
pub const USER_ID_START : usize = 201; pub const USER_ID_START : usize = 1001;
#[deprecated] #[deprecated]
#[allow(dead_code)] #[allow(dead_code)]
......
...@@ -75,6 +75,23 @@ impl MuType { ...@@ -75,6 +75,23 @@ impl MuType {
_ => None _ => None
} }
} }
pub fn get_int_length(&self) -> Option<usize> {
use types::MuType_::*;
match self.v {
Int(len) => Some(len),
Ref(_)
| IRef(_)
| WeakRef(_)
| UPtr(_)
| ThreadRef
| StackRef
| Tagref64
| FuncRef(_)
| UFuncPtr(_) => Some(64),
_ => None
}
}
} }
pub type StructTag = MuName; pub type StructTag = MuName;
...@@ -496,6 +513,6 @@ pub struct MuFuncSig { ...@@ -496,6 +513,6 @@ pub struct MuFuncSig {
impl fmt::Display for MuFuncSig { impl fmt::Display for MuFuncSig {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "[{}] -> [{}]", vec_utils::as_str(&self.ret_tys), vec_utils::as_str(&self.arg_tys)) write!(f, "[{}] -> [{}]", vec_utils::as_str(&self.arg_tys), vec_utils::as_str(&self.ret_tys))
} }
} }
...@@ -3,9 +3,7 @@ use ast::ir::*; ...@@ -3,9 +3,7 @@ use ast::ir::*;
use runtime::ValueLocation; use runtime::ValueLocation;
use compiler::machine_code::MachineCode; use compiler::machine_code::MachineCode;
use compiler::backend::{Reg, Mem};
pub type Reg<'a> = &'a P<Value>;
pub type Mem<'a> = &'a P<Value>;
pub trait CodeGenerator { pub trait CodeGenerator {
fn start_code(&mut self, func_name: MuName) -> ValueLocation; fn start_code(&mut self, func_name: MuName) -> ValueLocation;
...@@ -29,225 +27,108 @@ pub trait CodeGenerator { ...@@ -29,225 +27,108 @@ pub trait CodeGenerator {
fn emit_nop(&mut self, bytes: usize); fn emit_nop(&mut self, bytes: usize);
// comparison // comparison
fn emit_cmp_r64_r64 (&mut self, op1: Reg, op2: Reg); fn emit_cmp_r_r (&mut self, op1: Reg, op2: Reg);
fn emit_cmp_imm32_r64(&mut self, op1: i32, op2: Reg); fn emit_cmp_imm_r(&mut self, op1: i32, op2: Reg);
fn emit_cmp_mem64_r64(&mut self, op1: Mem, op2: Reg); fn emit_cmp_mem_r(&mut self, op1: Reg, op2: Reg);
fn emit_cmp_r32_r32 (&mut self, op1: Reg, op2: Reg);
fn emit_cmp_imm32_r32(&mut self, op1: i32, op2: Reg);
fn emit_cmp_mem32_r32(&mut self, op1: Mem, op2: Reg);
fn emit_cmp_r16_r16 (&mut self, op1: Reg, op2: Reg);
fn emit_cmp_imm16_r16(&mut self, op1: i16, op2: Reg);
fn emit_cmp_mem16_r16(&mut self, op1: Mem, op2: Reg);
fn emit_cmp_r8_r8 (&mut self, op1: Reg, op2: Reg);
fn emit_cmp_imm8_r8(&mut self, op1: i8, op2: Reg);
fn emit_cmp_mem8_r8(&mut self, op1: Mem, op2: Reg);
// gpr move // gpr move
fn emit_mov_r64_imm64 (&mut self, dest: Reg, src: i64); fn emit_mov_r64_imm64 (&mut self, dest: Reg, src: i64);
fn emit_mov_r64_imm32 (&mut self, dest: Reg, src: i32); fn emit_mov_r_imm (&mut self, dest: Reg, src: i32);
fn emit_mov_r64_mem64 (&mut self, dest: Reg, src: Mem); // load fn emit_mov_r_mem (&mut self, dest: Reg, src: Mem); // load
fn emit_mov_r64_r64 (&mut self, dest: Reg, src: Reg); fn emit_mov_r_r (&mut self, dest: Reg, src: Reg);
fn emit_mov_mem64_r64 (&mut self, dest: Mem, src: Reg); // store fn emit_mov_mem_r (&mut self, dest: Mem, src: Reg); // store
fn emit_mov_mem64_imm32(&mut self, dest: Mem, src: i32); fn emit_mov_mem_imm(&mut self, dest: Mem, src: i32); // store
fn emit_mov_r32_imm32 (&mut self, dest: Reg, src: i32); // zero/sign extend mov
fn emit_mov_r32_mem32 (&mut self, dest: Reg, src: Mem); // load fn emit_movs_r_r (&mut self, dest: Reg, src: Reg);
fn emit_mov_r32_r32 (&mut self, dest: Reg, src: Reg); fn emit_movz_r_r (&mut self, dest: Reg, src: Reg);
fn emit_mov_mem32_r32 (&mut self, dest: Mem, src: Reg); // store
fn emit_mov_mem32_imm32(&mut self, dest: Mem, src: i32);
fn emit_mov_r16_imm16 (&mut self, dest: Reg, src: i16);
fn emit_mov_r16_mem16 (&mut self, dest: Reg, src: Mem); // load
fn emit_mov_r16_r16 (&mut self, dest: Reg, src: Reg);
fn emit_mov_mem16_r16 (&mut self, dest: Mem, src: Reg); // store
fn emit_mov_mem16_imm16(&mut self, dest: Mem, src: i16);
fn emit_mov_r8_imm8 (&mut self, dest: Reg, src: i8);
fn emit_mov_r8_mem8 (&mut self, dest: Reg, src: Mem); // load
fn emit_mov_r8_r8 (&mut self, dest: Reg, src: Mem);
fn emit_mov_mem8_r8 (&mut self, dest: Mem, src: Reg); // store
fn emit_mov_mem8_imm8 (&mut self, dest: Mem, src: i8);
// gpr conditional move // gpr conditional move
fn emit_cmova_r64_r64 (&mut self, dest: Reg, src: Reg); fn emit_cmova_r_r (&mut self, dest: Reg, src: Reg);
fn emit_cmova_r64_mem64(&mut self, dest: Reg, src: Mem); // load fn emit_cmova_r_mem(&mut self, dest: Reg, src: Mem); // load
fn emit_cmovae_r64_r64 (&mut self, dest: Reg, src: Reg); fn emit_cmovae_r_r (&mut self, dest: Reg, src: Reg);
fn emit_cmovae_r64_mem64(&mut self, dest: Reg, src: Mem); // load fn emit_cmovae_r_mem(&mut self, dest: Reg, src: Mem); // load
fn emit_cmovb_r64_r64 (&mut self, dest: Reg, src: Reg); fn emit_cmovb_r_r (&mut self, dest: Reg, src: Reg);
fn emit_cmovb_r64_mem64(&mut self, dest: Reg, src: Mem); // load fn emit_cmovb_r_mem(&mut self, dest: Reg, src: Mem); // load
fn emit_cmovbe_r64_r64 (&mut self, dest: Reg, src: Reg); fn emit_cmovbe_r_r (&mut self, dest: Reg, src: Reg);
fn emit_cmovbe_r64_mem64(&mut self, dest: Reg, src: Mem); // load fn emit_cmovbe_r_mem(&mut self, dest: Reg, src: Mem); // load
fn emit_cmove_r64_r64 (&mut self, dest: Reg, src: Reg); fn emit_cmove_r_r (&mut self, dest: Reg, src: Reg);
fn emit_cmove_r64_mem64(&mut self, dest: Reg, src: Mem); // load fn emit_cmove_r_mem(&mut self, dest: Reg, src: Mem); // load
fn emit_cmovg_r64_r64 (&mut self, dest: Reg, src: Reg); fn emit_cmovg_r_r (&mut self, dest: Reg, src: Reg);
fn emit_cmovg_r64_mem64(&mut self, dest: Reg, src: Mem); // load fn emit_cmovg_r_mem(&mut self, dest: Reg, src: Mem); // load
fn emit_cmovge_r64_r64 (&mut self, dest: Reg, src: Reg); fn emit_cmovge_r_r (&mut self, dest: Reg, src: Reg);
fn emit_cmovge_r64_mem64(&mut self, dest: Reg, src: Mem); // load fn emit_cmovge_r_mem(&mut self, dest: Reg, src: Mem); // load
fn emit_cmovl_r64_r64 (&mut self, dest: Reg, src: Reg); fn emit_cmovl_r_r (&mut self, dest: Reg, src: Reg);
fn emit_cmovl_r64_mem64(&mut self, dest: Reg, src: Mem); // load fn emit_cmovl_r_mem(&mut self, dest: Reg, src: Mem); // load
fn emit_cmovle_r64_r64 (&mut self, dest: Reg, src: Reg); fn emit_cmovle_r_r (&mut self, dest: Reg, src: Reg);
fn emit_cmovle_r64_mem64(&mut self, dest: Reg, src: Mem); // load fn emit_cmovle_r_mem(&mut self, dest: Reg, src: Mem); // load
fn emit_cmovne_r64_r64 (&mut self, dest: Reg, src: Reg); fn emit_cmovne_r_r (&mut self, dest: Reg, src: Reg);
fn emit_cmovne_r64_mem64(&mut self, dest: Reg, src: Mem); // load fn emit_cmovne_r_mem(&mut self, dest: Reg, src: Mem); // load
// lea // lea
fn emit_lea_r64(&mut self, dest: Reg, src: Mem); fn emit_lea_r64(&mut self, dest: Reg, src: Mem);
// and // and
fn emit_and_r64_imm32(&mut self, dest: Reg, src: i32); fn emit_and_r_imm(&mut self, dest: Reg, src: i32);
fn emit_and_r64_r64 (&mut self, dest: Reg, src: Reg); fn emit_and_r_r (&mut self, dest: Reg, src: Reg);
fn emit_and_r64_mem64(&mut self, dest: Reg, src: Mem); fn emit_and_r_mem(&mut self, dest: Reg, src: Mem);
fn emit_and_r32_imm32(&mut self, dest: Reg, src: i32);
fn emit_and_r32_r32 (&mut self, dest: Reg, src: Reg);
fn emit_and_r32_mem32(&mut self, dest: Reg, src: Mem);
fn emit_and_r16_imm16(&mut self, dest: Reg, src: i16);
fn emit_and_r16_r16 (&mut self, dest: Reg, src: Reg);
fn emit_and_r16_mem16(&mut self, dest: Reg, src: Mem);
fn emit_and_r8_imm8 (&mut self, dest: Reg, src: i8); // or
fn emit_and_r8_r8 (&mut self, dest: Reg, src: Reg); fn emit_or_r_r (&mut self, dest: Reg, src: Reg);
fn emit_and_r8_mem8 (&mut self, dest: Reg, src: Mem); fn emit_or_r_imm(&mut self, dest: Reg, src: i32);
fn emit_or_r_mem(&mut self, dest: Reg, src: Mem);
// xor // xor
fn emit_xor_r64_r64 (&mut self, dest: Reg, src: Reg); fn emit_xor_r_r (&mut self, dest: Reg, src: Reg);
fn emit_xor_r64_mem64(&mut self, dest: Reg, src: Mem); fn emit_xor_r_mem(&mut self, dest: Reg, src: Mem);
fn emit_xor_r64_imm32(&mut self, dest: Reg, src: i32); fn emit_xor_r_imm(&mut self, dest: Reg, src: i32);
fn emit_xor_r32_r32 (&mut self, dest: Reg, src: Reg);
fn emit_xor_r32_mem32(&mut self, dest: Reg, src: Mem);
fn emit_xor_r32_imm32(&mut self, dest: Reg, src: i32);
fn emit_xor_r16_r16 (&mut self, dest: Reg, src: Reg);
fn emit_xor_r16_mem16(&mut self, dest: Reg, src: Reg);
fn emit_xor_r16_imm16(&mut self, dest: Reg, src: i16);
fn emit_xor_r8_r8 (&mut self, dest: Reg, src: Reg);
fn emit_xor_r8_mem8 (&mut self, dest: Reg, src: Reg);
fn emit_xor_r8_imm8 (&mut self, dest: Reg, src: i8);
// add // add
fn emit_add_r64_r64 (&mut self, dest: Reg, src: Reg); fn emit_add_r_r (&mut self, dest: Reg, src: Reg);
fn emit_add_r64_mem64(&mut self, dest: Reg, src: Mem); fn emit_add_r_mem(&mut self, dest: Reg, src: Mem);
fn emit_add_r64_imm32(&mut self, dest: Reg, src: i32); fn emit_add_r_imm(&mut self, dest: Reg, src: i32);
fn emit_add_r32_r32 (&mut self, dest: Reg, src: Reg);
fn emit_add_r32_mem32(&mut self, dest: Reg, src: Mem);
fn emit_add_r32_imm32(&mut self, dest: Reg, src: i32);
fn emit_add_r16_r16 (&mut self, dest: Reg, src: Reg);
fn emit_add_r16_mem16(&mut self, dest: Reg, src: Mem);
fn emit_add_r16_imm16(&mut self, dest: Reg, src: i16);
fn emit_add_r8_r8 (&mut self, dest: Reg, src: Reg);
fn emit_add_r8_mem8(&mut self, dest: Reg, src: Mem);
fn emit_add_r8_imm8(&mut self, dest: Reg, src: i8);
// or
fn emit_or_r64_r64 (&mut self, dest: Reg, src: Reg);
fn emit_or_r64_imm32(&mut self, dest: Reg, src: i32);
fn emit_or_r64_mem64(&mut self, dest: Reg, src: Mem);
// sub // sub
fn emit_sub_r64_r64 (&mut self, dest: Reg, src: Reg); fn emit_sub_r_r (&mut self, dest: Reg, src: Reg);
fn emit_sub_r64_mem64(&mut self, dest: Reg, src: Mem); fn emit_sub_r_mem(&mut self, dest: Reg, src: Mem);
fn emit_sub_r64_imm32(&mut self, dest: Reg, src: i32); fn emit_sub_r_imm(&mut self, dest: Reg, src: i32);
fn emit_sub_r32_r32 (&mut self, dest: Reg, src: Reg);
fn emit_sub_r32_mem32(&mut self, dest: Reg, src: Mem);
fn emit_sub_r32_imm32(&mut self, dest: Reg, src: i32);
fn emit_sub_r16_r16 (&mut self, dest: Reg, src: Reg);
fn emit_sub_r16_mem16(&mut self, dest: Reg, src: Mem);
fn emit_sub_r16_imm16(&mut self, dest: Reg, src: i16);
fn emit_sub_r8_r8 (&mut self, dest: Reg, src: Reg);
fn emit_sub_r8_mem8(&mut self, dest: Reg, src: Mem);
fn emit_sub_r8_imm8(&mut self, dest: Reg, src: i8);
// floating point // floating point
fn emit_addsd_f64_f64 (&mut self, dest: Reg, src: Reg); fn emit_addsd_f64_f64 (&mut self, dest: Reg, src: Reg);
fn emit_addsd_f64_mem64(&mut self, dest: Reg, src: Mem); fn emit_addsd_f64_mem64(&mut self, dest: Reg, src: Mem);
// multiply // multiply
fn emit_mul_r64 (&mut self, src: Reg); fn emit_mul_r (&mut self, src: Reg);
fn emit_mul_r32 (&mut self, src: Reg); fn emit_mul_mem(&mut self, src: Mem);
fn emit_mul_r16 (&mut self, src: Reg);
fn emit_mul_r8 (&mut self, src: Reg);
fn emit_mul_mem64(&mut self, src: Mem);
fn emit_mul_mem32(&mut self, src: Mem);
fn emit_mul_mem16(&mut self, src: Mem);
fn emit_mul_mem8 (&mut self, src: Mem);
// div // div
fn emit_div_r64 (&mut self, src: Reg); fn emit_div_r (&mut self, src: Reg);
fn emit_div_r32 (&mut self, src: Reg); fn emit_div_mem (&mut self, src: Mem);
fn emit_div_r16 (&mut self, src: Reg);
fn emit_div_r8 (&mut self, src: Reg);
fn emit_div_mem64 (&mut self, src: Mem);
fn emit_div_mem32 (&mut self, src: Mem);
fn emit_div_mem16 (&mut self, src: Mem);
fn emit_div_mem8 (&mut self, src: Mem);
// idiv // idiv
fn emit_idiv_r64 (&mut self, src: Reg); fn emit_idiv_r (&mut self, src: Reg);
fn emit_idiv_r32 (&mut self, src: Reg); fn emit_idiv_mem(&mut self, src: Mem);
fn emit_idiv_r16 (&mut self, src: Reg);
fn emit_idiv_r8 (&mut self, src: Reg);
fn emit_idiv_mem64(&mut self, src: Mem);
fn emit_idiv_mem32(&mut self, src: Mem);
fn emit_idiv_mem16(&mut self, src: Mem);
fn emit_idiv_mem8 (&mut self, src: Mem);
// shl // shl
fn emit_shl_r64_cl (&mut self, dest: Reg); fn emit_shl_r_cl (&mut self, dest: Reg);
// fn emit_shl_r32_cl (&mut self, dest: Reg); fn emit_shl_r_imm8 (&mut self, dest: Reg, src: i8);
// fn emit_shl_r16_cl (&mut self, dest: Reg);
// fn emit_shl_r8_cl (&mut self, dest: Reg); fn emit_shr_r_cl (&mut self, dest: &P<Value>);
fn emit_shr_r_imm8 (&mut self, dest: &P<Value>, src: i8);
fn emit_shl_mem64_cl (&mut self, dest: Mem);
// fn emit_shl_mem32_cl (&mut self, dest: Mem); fn emit_sar_r_cl (&mut self, dest: &P<Value>);
// fn emit_shl_mem16_cl (&mut self, dest: Mem); fn emit_sar_r_imm8 (&mut self, dest: &P<Value>, src: i8);
// fn emit_shl_mem8_cl (&mut self, dest: Mem);
fn emit_shl_r64_imm8 (&mut self, dest: Reg, src: i8);
// fn emit_shl_r32_imm8 (&mut self, dest: Reg, src: i8);
// fn emit_shl_r16_imm8 (&mut self, dest: Reg, src: i8);
// fn emit_shl_r8_imm8 (&mut self, dest: Reg, src: i8);
fn emit_shl_mem64_imm8(&mut self, dest: Mem, src: i8);
// fn emit_shl_mem32_imm8(&mut self, dest: Mem, src: i8);
// fn emit_shl_mem16_imm8(&mut self, dest: Mem, src: i8);
// fn emit_shl_mem8_imm8 (&mut self, dest: Mem, src: i8);
fn emit_shr_r64_cl (&mut self, dest: &P<Value>);
fn emit_shr_mem64_cl (&mut self, dest: &P<Value>);
fn emit_shr_r64_imm8 (&mut self, dest: &P<Value>, src: i8);
fn emit_shr_mem64_imm8(&mut self, dest: &P<Value>, src: i8);
fn emit_sar_r64_cl (&mut self, dest: &P<Value>);
fn emit_sar_mem64_cl (&mut self, dest: &P<Value>);
fn emit_sar_r64_imm8 (&mut self, dest: &P<Value>, src: i8);
fn emit_sar_mem64_imm8(&mut self, dest: &P<Value>, src: i8);
fn emit_cqo(&mut self); fn emit_cqo(&mut self);
......
...@@ -21,6 +21,18 @@ use compiler::backend::RegGroup; ...@@ -21,6 +21,18 @@ use compiler::backend::RegGroup;
use std::collections::HashMap; use std::collections::HashMap;
macro_rules! GPR_ALIAS { macro_rules! GPR_ALIAS {
($alias: ident: ($id64: expr, $r64: ident) -> $r32: ident, $r16: ident, $r8l: ident, $r8h: ident) => {
lazy_static!{
pub static ref $r64 : P<Value> = GPR!($id64, stringify!($r64), UINT64_TYPE);
pub static ref $r32 : P<Value> = GPR!($id64 +1, stringify!($r32), UINT32_TYPE);
pub static ref $r16 : P<Value> = GPR!($id64 +2, stringify!($r16), UINT16_TYPE);
pub static ref $r8l : P<Value> = GPR!($id64 +3, stringify!($r8l), UINT8_TYPE);
pub static ref $r8h : P<Value> = GPR!($id64 +4, stringify!($r8h), UINT8_TYPE);
pub static ref $alias : [P<Value>; 5] = [$r64.clone(), $r32.clone(), $r16.clone(), $r8l.clone(), $r8h.clone()];
}
};
($alias: ident: ($id64: expr, $r64: ident) -> $r32: ident, $r16: ident, $r8: ident) => { ($alias: ident: ($id64: expr, $r64: ident) -> $r32: ident, $r16: ident, $r8: ident) => {
lazy_static!{ lazy_static!{
pub static ref $r64 : P<Value> = GPR!($id64, stringify!($r64), UINT64_TYPE); pub static ref $r64 : P<Value> = GPR!($id64, stringify!($r64), UINT64_TYPE);
...@@ -65,26 +77,26 @@ macro_rules! FPR { ...@@ -65,26 +77,26 @@ macro_rules! FPR {
}; };
} }
GPR_ALIAS!(RAX_ALIAS: (0, RAX) -> EAX, AX , AL); GPR_ALIAS!(RAX_ALIAS: (0, RAX) -> EAX, AX , AL, AH);
GPR_ALIAS!(RCX_ALIAS: (4, RCX) -> ECX, CX , CL); GPR_ALIAS!(RCX_ALIAS: (5, RCX) -> ECX, CX , CL, CH);
GPR_ALIAS!(RDX_ALIAS: (8, RDX) -> EDX, DX , DL); GPR_ALIAS!(RDX_ALIAS: (10, RDX) -> EDX, DX , DL, DH);
GPR_ALIAS!(RBX_ALIAS: (12,RBX) -> EBX, BX , BL); GPR_ALIAS!(RBX_ALIAS: (15,RBX) -> EBX, BX , BL, BH);
GPR_ALIAS!(RSP_ALIAS: (16,RSP) -> ESP, SP , SPL); GPR_ALIAS!(RSP_ALIAS: (20,RSP) -> ESP, SP , SPL);
GPR_ALIAS!(RBP_ALIAS: (20,RBP) -> EBP, BP , BPL); GPR_ALIAS!(RBP_ALIAS: (24,RBP) -> EBP, BP , BPL);
GPR_ALIAS!(RSI_ALIAS: (24,RSI) -> ESI, SI , SIL); GPR_ALIAS!(RSI_ALIAS: (28,RSI) -> ESI, SI , SIL);
GPR_ALIAS!(RDI_ALIAS: (28,RDI) -> EDI, DI , DIL); GPR_ALIAS!(RDI_ALIAS: (32,RDI) -> EDI, DI , DIL);
GPR_ALIAS!(R8_ALIAS : (32,R8 ) -> R8D, R8W, R8L); GPR_ALIAS!(R8_ALIAS : (36,R8 ) -> R8D, R8W, R8B);
GPR_ALIAS!(R9_ALIAS : (36,R9 ) -> R9D, R9W, R9L); GPR_ALIAS!(R9_ALIAS : (40,R9 ) -> R9D, R9W, R9B);
GPR_ALIAS!(R10_ALIAS: (40,R10) -> R10D,R10W,R10L); GPR_ALIAS!(R10_ALIAS: (44,R10) -> R10D,R10W,R10B);
GPR_ALIAS!(R11_ALIAS: (44,R11) -> R11D,R11W,R11L); GPR_ALIAS!(R11_ALIAS: (48,R11) -> R11D,R11W,R11B);
GPR_ALIAS!(R12_ALIAS: (48,R12) -> R12D,R12W,R12L); GPR_ALIAS!(R12_ALIAS: (52,R12) -> R12D,R12W,R12B);
GPR_ALIAS!(R13_ALIAS: (52,R13) -> R13D,R13W,R13L); GPR_ALIAS!(R13_ALIAS: (56,R13) -> R13D,R13W,R13B);
GPR_ALIAS!(R14_ALIAS: (56,R14) -> R14D,R14W,R14L); GPR_ALIAS!(R14_ALIAS: (60,R14) -> R14D,R14W,R14B);
GPR_ALIAS!(R15_ALIAS: (60,R15) -> R15D,R15W,R15L); GPR_ALIAS!(R15_ALIAS: (64,R15) -> R15D,R15W,R15B);
GPR_ALIAS!(RIP_ALIAS: (64,RIP)); GPR_ALIAS!(RIP_ALIAS: (68,RIP));
lazy_static! { lazy_static! {
pub static ref GPR_ALIAS_LOOKUP_TABLE : HashMap<MuID, Vec<P<Value>>> = { pub static ref GPR_ALIAS_TABLE : HashMap<MuID, Vec<P<Value>>> = {
let mut ret = HashMap::new(); let mut ret = HashMap::new();
ret.insert(RAX.id(), RAX_ALIAS.to_vec()); ret.insert(RAX.id(), RAX_ALIAS.to_vec());
...@@ -107,20 +119,58 @@ lazy_static! { ...@@ -107,20 +119,58 @@ lazy_static! {
ret ret
}; };
}
pub fn get_gpr_alias(id: MuID, length: usize) -> P<Value> { // e.g. given eax, return rax
let vec = match GPR_ALIAS_LOOKUP_TABLE.get(&id) { pub static ref GPR_ALIAS_LOOKUP : HashMap<MuID, P<Value>> = {
Some(vec) => vec, let mut ret = HashMap::new();
None => panic!("didnt find {} as GPR", id)
for vec in GPR_ALIAS_TABLE.values() {
let colorable = vec[0].clone();
for gpr in vec {
ret.insert(gpr.id(), colorable.clone());
}
}
ret
}; };
}
pub fn get_alias_for_length(id: MuID, length: usize) -> P<Value> {
if id < FPR_ID_START {
let vec = match GPR_ALIAS_TABLE.get(&id) {
Some(vec) => vec,
None => panic!("didnt find {} as GPR", id)
};
match length {
64 => vec[0].clone(),
32 => vec[1].clone(),
16 => vec[2].clone(),
8 => vec[3].clone(),
1 => vec[3].clone(),
_ => panic!("unexpected length {} for {}", length, vec[0])
}
} else {
for r in ALL_FPRs.iter() {
if r.id() == id {
return r.clone();
}
}
match length { panic!("didnt find {} as FPR", id)
64 => vec[0].clone(), }
32 => vec[1].clone(), }
16 => vec[2].clone(),
8 => vec[3].clone(), pub fn get_color_for_precolroed(id: MuID) -> MuID {
_ => panic!("unexpected length: {}", length) if id < FPR_ID_START {
match GPR_ALIAS_LOOKUP.get(&id) {
Some(val) => val.id(),
None => panic!("cannot find GPR {}", id)
}
} else {
// we do not have alias for FPRs
id
} }
} }
...@@ -160,7 +210,7 @@ lazy_static! { ...@@ -160,7 +210,7 @@ lazy_static! {
R11.clone() R11.clone()
]; ];
pub static ref ALL_GPRs : [P<Value>; 15] = [ static ref ALL_GPRs : [P<Value>; 15] = [
RAX.clone(), RAX.clone(),
RCX.clone(), RCX.clone(),
RDX.clone(), RDX.clone(),
...@@ -180,23 +230,25 @@ lazy_static! { ...@@ -180,23 +230,25 @@ lazy_static! {
]; ];
} }
pub const FPR_ID_START : usize = 100;
lazy_static!{ lazy_static!{
pub static ref XMM0 : P<Value> = FPR!(70,"xmm0"); pub static ref XMM0 : P<Value> = FPR!(FPR_ID_START, "xmm0");