WARNING! Access to this system is limited to authorised users only.
Unauthorised users may be subject to prosecution.
Unauthorised access to this system is a criminal offence under Australian law (Federal Crimes Act 1914 Part VIA)
It is a criminal offence to:
(1) Obtain access to data without authority. -Penalty 2 years imprisonment.
(2) Damage, delete, alter or insert data without authority. -Penalty 10 years imprisonment.
User activity is monitored and recorded. Anyone using this system expressly consents to such monitoring and recording.

To protect your data, the CISO officer has suggested users to enable 2FA as soon as possible.
Currently 2.6% of users enabled 2FA.

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,