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.3% 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! {
};
}
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_END : usize = 200;
pub const USER_ID_START : usize = 201;
pub const INTERNAL_ID_START: usize = 201;
pub const INTERNAL_ID_END : usize = 500;
pub const USER_ID_START : usize = 1001;
#[deprecated]
#[allow(dead_code)]
......
......@@ -75,6 +75,23 @@ impl MuType {
_ => 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;
......@@ -496,6 +513,6 @@ pub struct MuFuncSig {
impl fmt::Display for MuFuncSig {
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::*;
use runtime::ValueLocation;
use compiler::machine_code::MachineCode;
pub type Reg<'a> = &'a P<Value>;
pub type Mem<'a> = &'a P<Value>;
use compiler::backend::{Reg, Mem};
pub trait CodeGenerator {
fn start_code(&mut self, func_name: MuName) -> ValueLocation;
......@@ -29,225 +27,108 @@ pub trait CodeGenerator {
fn emit_nop(&mut self, bytes: usize);
// comparison
fn emit_cmp_r64_r64 (&mut self, op1: Reg, op2: Reg);
fn emit_cmp_imm32_r64(&mut self, op1: i32, op2: Reg);
fn emit_cmp_mem64_r64(&mut self, op1: Mem, 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);
fn emit_cmp_r_r (&mut self, op1: Reg, op2: Reg);
fn emit_cmp_imm_r(&mut self, op1: i32, op2: Reg);
fn emit_cmp_mem_r(&mut self, op1: Reg, op2: Reg);
// gpr move
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_r64_mem64 (&mut self, dest: Reg, src: Mem); // load
fn emit_mov_r64_r64 (&mut self, dest: Reg, src: Reg);
fn emit_mov_mem64_r64 (&mut self, dest: Mem, src: Reg); // store
fn emit_mov_mem64_imm32(&mut self, dest: Mem, src: i32);
fn emit_mov_r32_imm32 (&mut self, dest: Reg, src: i32);
fn emit_mov_r32_mem32 (&mut self, dest: Reg, src: Mem); // load
fn emit_mov_r32_r32 (&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);
fn emit_mov_r_imm (&mut self, dest: Reg, src: i32);
fn emit_mov_r_mem (&mut self, dest: Reg, src: Mem); // load
fn emit_mov_r_r (&mut self, dest: Reg, src: Reg);
fn emit_mov_mem_r (&mut self, dest: Mem, src: Reg); // store
fn emit_mov_mem_imm(&mut self, dest: Mem, src: i32); // store
// zero/sign extend mov
fn emit_movs_r_r (&mut self, dest: Reg, src: Reg);
fn emit_movz_r_r (&mut self, dest: Reg, src: Reg);
// gpr conditional move
fn emit_cmova_r64_r64 (&mut self, dest: Reg, src: Reg);
fn emit_cmova_r64_mem64(&mut self, dest: Reg, src: Mem); // load
fn emit_cmova_r_r (&mut self, dest: Reg, src: Reg);
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_r64_mem64(&mut self, dest: Reg, src: Mem); // load
fn emit_cmovae_r_r (&mut self, dest: Reg, src: Reg);
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_r64_mem64(&mut self, dest: Reg, src: Mem); // load
fn emit_cmovb_r_r (&mut self, dest: Reg, src: Reg);
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_r64_mem64(&mut self, dest: Reg, src: Mem); // load
fn emit_cmovbe_r_r (&mut self, dest: Reg, src: Reg);
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_r64_mem64(&mut self, dest: Reg, src: Mem); // load
fn emit_cmove_r_r (&mut self, dest: Reg, src: Reg);
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_r64_mem64(&mut self, dest: Reg, src: Mem); // load
fn emit_cmovg_r_r (&mut self, dest: Reg, src: Reg);
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_r64_mem64(&mut self, dest: Reg, src: Mem); // load
fn emit_cmovge_r_r (&mut self, dest: Reg, src: Reg);
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_r64_mem64(&mut self, dest: Reg, src: Mem); // load
fn emit_cmovl_r_r (&mut self, dest: Reg, src: Reg);
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_r64_mem64(&mut self, dest: Reg, src: Mem); // load
fn emit_cmovle_r_r (&mut self, dest: Reg, src: Reg);
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_r64_mem64(&mut self, dest: Reg, src: Mem); // load
fn emit_cmovne_r_r (&mut self, dest: Reg, src: Reg);
fn emit_cmovne_r_mem(&mut self, dest: Reg, src: Mem); // load
// lea
fn emit_lea_r64(&mut self, dest: Reg, src: Mem);
// and
fn emit_and_r64_imm32(&mut self, dest: Reg, src: i32);
fn emit_and_r64_r64 (&mut self, dest: Reg, src: Reg);
fn emit_and_r64_mem64(&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_r_imm(&mut self, dest: Reg, src: i32);
fn emit_and_r_r (&mut self, dest: Reg, src: Reg);
fn emit_and_r_mem(&mut self, dest: Reg, src: Mem);
fn emit_and_r8_imm8 (&mut self, dest: Reg, src: i8);
fn emit_and_r8_r8 (&mut self, dest: Reg, src: Reg);
fn emit_and_r8_mem8 (&mut self, dest: Reg, src: Mem);
// or
fn emit_or_r_r (&mut self, dest: Reg, src: Reg);
fn emit_or_r_imm(&mut self, dest: Reg, src: i32);
fn emit_or_r_mem(&mut self, dest: Reg, src: Mem);
// xor
fn emit_xor_r64_r64 (&mut self, dest: Reg, src: Reg);
fn emit_xor_r64_mem64(&mut self, dest: Reg, src: Mem);
fn emit_xor_r64_imm32(&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);
fn emit_xor_r_r (&mut self, dest: Reg, src: Reg);
fn emit_xor_r_mem(&mut self, dest: Reg, src: Mem);
fn emit_xor_r_imm(&mut self, dest: Reg, src: i32);
// add
fn emit_add_r64_r64 (&mut self, dest: Reg, src: Reg);
fn emit_add_r64_mem64(&mut self, dest: Reg, src: Mem);
fn emit_add_r64_imm32(&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);
fn emit_add_r_r (&mut self, dest: Reg, src: Reg);
fn emit_add_r_mem(&mut self, dest: Reg, src: Mem);
fn emit_add_r_imm(&mut self, dest: Reg, src: i32);
// sub
fn emit_sub_r64_r64 (&mut self, dest: Reg, src: Reg);
fn emit_sub_r64_mem64(&mut self, dest: Reg, src: Mem);
fn emit_sub_r64_imm32(&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);
fn emit_sub_r_r (&mut self, dest: Reg, src: Reg);
fn emit_sub_r_mem(&mut self, dest: Reg, src: Mem);
fn emit_sub_r_imm(&mut self, dest: Reg, src: i32);
// floating point
fn emit_addsd_f64_f64 (&mut self, dest: Reg, src: Reg);
fn emit_addsd_f64_mem64(&mut self, dest: Reg, src: Mem);
// multiply
fn emit_mul_r64 (&mut self, src: Reg);
fn emit_mul_r32 (&mut self, src: Reg);
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);
fn emit_mul_r (&mut self, src: Reg);
fn emit_mul_mem(&mut self, src: Mem);
// div
fn emit_div_r64 (&mut self, src: Reg);
fn emit_div_r32 (&mut self, src: Reg);
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);
fn emit_div_r (&mut self, src: Reg);
fn emit_div_mem (&mut self, src: Mem);
// idiv
fn emit_idiv_r64 (&mut self, src: Reg);
fn emit_idiv_r32 (&mut self, src: Reg);
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);
fn emit_idiv_r (&mut self, src: Reg);
fn emit_idiv_mem(&mut self, src: Mem);
// shl
fn emit_shl_r64_cl (&mut self, dest: Reg);
// fn emit_shl_r32_cl (&mut self, dest: Reg);
// fn emit_shl_r16_cl (&mut self, dest: Reg);
// fn emit_shl_r8_cl (&mut self, dest: Reg);
fn emit_shl_mem64_cl (&mut self, dest: Mem);
// fn emit_shl_mem32_cl (&mut self, dest: Mem);
// fn emit_shl_mem16_cl (&mut self, dest: Mem);
// 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_shl_r_cl (&mut self, dest: Reg);
fn emit_shl_r_imm8 (&mut self, dest: Reg, src: i8);
fn emit_shr_r_cl (&mut self, dest: &P<Value>);
fn emit_shr_r_imm8 (&mut self, dest: &P<Value>, src: i8);
fn emit_sar_r_cl (&mut self, dest: &P<Value>);
fn emit_sar_r_imm8 (&mut self, dest: &P<Value>, src: i8);
fn emit_cqo(&mut self);
......
......@@ -21,6 +21,18 @@ use compiler::backend::RegGroup;
use std::collections::HashMap;
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) => {
lazy_static!{
pub static ref $r64 : P<Value> = GPR!($id64, stringify!($r64), UINT64_TYPE);
......@@ -65,26 +77,26 @@ macro_rules! FPR {
};
}
GPR_ALIAS!(RAX_ALIAS: (0, RAX) -> EAX, AX , AL);
GPR_ALIAS!(RCX_ALIAS: (4, RCX) -> ECX, CX , CL);
GPR_ALIAS!(RDX_ALIAS: (8, RDX) -> EDX, DX , DL);
GPR_ALIAS!(RBX_ALIAS: (12,RBX) -> EBX, BX , BL);
GPR_ALIAS!(RSP_ALIAS: (16,RSP) -> ESP, SP , SPL);
GPR_ALIAS!(RBP_ALIAS: (20,RBP) -> EBP, BP , BPL);
GPR_ALIAS!(RSI_ALIAS: (24,RSI) -> ESI, SI , SIL);
GPR_ALIAS!(RDI_ALIAS: (28,RDI) -> EDI, DI , DIL);
GPR_ALIAS!(R8_ALIAS : (32,R8 ) -> R8D, R8W, R8L);
GPR_ALIAS!(R9_ALIAS : (36,R9 ) -> R9D, R9W, R9L);
GPR_ALIAS!(R10_ALIAS: (40,R10) -> R10D,R10W,R10L);
GPR_ALIAS!(R11_ALIAS: (44,R11) -> R11D,R11W,R11L);
GPR_ALIAS!(R12_ALIAS: (48,R12) -> R12D,R12W,R12L);
GPR_ALIAS!(R13_ALIAS: (52,R13) -> R13D,R13W,R13L);
GPR_ALIAS!(R14_ALIAS: (56,R14) -> R14D,R14W,R14L);
GPR_ALIAS!(R15_ALIAS: (60,R15) -> R15D,R15W,R15L);
GPR_ALIAS!(RIP_ALIAS: (64,RIP));
GPR_ALIAS!(RAX_ALIAS: (0, RAX) -> EAX, AX , AL, AH);
GPR_ALIAS!(RCX_ALIAS: (5, RCX) -> ECX, CX , CL, CH);
GPR_ALIAS!(RDX_ALIAS: (10, RDX) -> EDX, DX , DL, DH);
GPR_ALIAS!(RBX_ALIAS: (15,RBX) -> EBX, BX , BL, BH);
GPR_ALIAS!(RSP_ALIAS: (20,RSP) -> ESP, SP , SPL);
GPR_ALIAS!(RBP_ALIAS: (24,RBP) -> EBP, BP , BPL);
GPR_ALIAS!(RSI_ALIAS: (28,RSI) -> ESI, SI , SIL);
GPR_ALIAS!(RDI_ALIAS: (32,RDI) -> EDI, DI , DIL);
GPR_ALIAS!(R8_ALIAS : (36,R8 ) -> R8D, R8W, R8B);
GPR_ALIAS!(R9_ALIAS : (40,R9 ) -> R9D, R9W, R9B);
GPR_ALIAS!(R10_ALIAS: (44,R10) -> R10D,R10W,R10B);
GPR_ALIAS!(R11_ALIAS: (48,R11) -> R11D,R11W,R11B);
GPR_ALIAS!(R12_ALIAS: (52,R12) -> R12D,R12W,R12B);
GPR_ALIAS!(R13_ALIAS: (56,R13) -> R13D,R13W,R13B);
GPR_ALIAS!(R14_ALIAS: (60,R14) -> R14D,R14W,R14B);
GPR_ALIAS!(R15_ALIAS: (64,R15) -> R15D,R15W,R15B);
GPR_ALIAS!(RIP_ALIAS: (68,RIP));
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();
ret.insert(RAX.id(), RAX_ALIAS.to_vec());
......@@ -107,20 +119,58 @@ lazy_static! {
ret
};
}
pub fn get_gpr_alias(id: MuID, length: usize) -> P<Value> {
let vec = match GPR_ALIAS_LOOKUP_TABLE.get(&id) {
Some(vec) => vec,
None => panic!("didnt find {} as GPR", id)
// e.g. given eax, return rax
pub static ref GPR_ALIAS_LOOKUP : HashMap<MuID, P<Value>> = {
let mut ret = HashMap::new();
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 {
64 => vec[0].clone(),
32 => vec[1].clone(),
16 => vec[2].clone(),
8 => vec[3].clone(),
_ => panic!("unexpected length: {}", length)
panic!("didnt find {} as FPR", id)
}
}
pub fn get_color_for_precolroed(id: MuID) -> MuID {
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! {
R11.clone()
];
pub static ref ALL_GPRs : [P<Value>; 15] = [
static ref ALL_GPRs : [P<Value>; 15] = [
RAX.clone(),
RCX.clone(),
RDX.clone(),
......@@ -180,23 +230,25 @@ lazy_static! {
];
}
pub const FPR_ID_START : usize = 100;
lazy_static!{
pub static ref XMM0 : P<Value> = FPR!(70,"xmm0");
pub static ref XMM1 : P<Value> = FPR!(71,"xmm1");
pub static ref XMM2 : P<Value> = FPR!(72,"xmm2");
pub static ref XMM3 : P<Value> = FPR!(73,"xmm3");
pub static ref XMM4 : P<Value> = FPR!(74,"xmm4");
pub static ref XMM5 : P<Value> = FPR!(75,"xmm5");
pub static ref XMM6 : P<Value> = FPR!(76,"xmm6");
pub static ref XMM7 : P<Value> = FPR!(77,"xmm7");
pub static ref XMM8 : P<Value> = FPR!(78,"xmm8");
pub static ref XMM9 : P<Value> = FPR!(79,"xmm9");
pub static ref XMM10 : P<Value> = FPR!(80,"xmm10");
pub static ref XMM11 : P<Value> = FPR!(81,"xmm11");
pub static ref XMM12 : P<Value> = FPR!(82,"xmm12");
pub static ref XMM13 : P<Value> = FPR!(83,"xmm13");
pub static ref XMM14 : P<Value> = FPR!(84,"xmm14");
pub static ref XMM15 : P<Value> = FPR!(85,"xmm15");
pub static ref XMM0 : P<Value> = FPR!(FPR_ID_START, "xmm0");
pub static ref XMM1 : P<Value> = FPR!(FPR_ID_START + 1,"xmm1");
pub static ref XMM2 : P<Value> = FPR!(FPR_ID_START + 2,"xmm2");
pub static ref XMM3 : P<Value> = FPR!(FPR_ID_START + 3,"xmm3");
pub static ref XMM4 : P<Value> = FPR!(FPR_ID_START + 4,"xmm4");
pub static ref XMM5 : P<Value> = FPR!(FPR_ID_START + 5,"xmm5");
pub static ref XMM6 : P<Value> = FPR!(FPR_ID_START + 6,"xmm6");
pub static ref XMM7 : P<Value> = FPR!(FPR_ID_START + 7,"xmm7");
pub static ref XMM8 : P<Value> = FPR!(FPR_ID_START + 8,"xmm8");
pub static ref XMM9 : P<Value> = FPR!(FPR_ID_START + 9,"xmm9");
pub static ref XMM10 : P<Value> = FPR!(FPR_ID_START + 10,"xmm10");
pub static ref XMM11 : P<Value> = FPR!(FPR_ID_START + 11,"xmm11");
pub static ref XMM12 : P<Value> = FPR!(FPR_ID_START + 12,"xmm12");
pub static ref XMM13 : P<Value> = FPR!(FPR_ID_START + 13,"xmm13");
pub static ref XMM14 : P<Value> = FPR!(FPR_ID_START + 14,"xmm14");
pub static ref XMM15 : P<Value> = FPR!(FPR_ID_START + 15,"xmm15");
pub static ref RETURN_FPRs : [P<Value>; 2] = [
XMM0.clone(),
......@@ -235,7 +287,7 @@ lazy_static!{
XMM15.clone(),
];
pub static ref ALL_FPRs : [P<Value>; 16] = [
static ref ALL_FPRs : [P<Value>; 16] = [
XMM0.clone(),
XMM1.clone(),
XMM2.clone(),
......@@ -255,28 +307,16 @@ lazy_static!{
];
}
pub const GPR_COUNT : usize = 16;
pub const FPR_COUNT : usize = 16;
lazy_static! {
pub static ref ALL_MACHINE_REGs : HashMap<MuID, P<Value>> = {
let mut map = HashMap::new();
map.insert(RAX.id(), RAX.clone());
map.insert(RCX.id(), RCX.clone());