To protect your data, the CISO officer has suggested users to enable GitLab 2FA as soon as possible.

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());
map.insert(RDX.id(), RDX.clone());