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.2% of users enabled 2FA.

Commit dba7a91a authored by qinsoon's avatar qinsoon
Browse files

[wip] refactor: remove is_int_reg()/is_fp_reg() from Value, always check

with RegGroup::get_from_value
parent 884a5109
......@@ -702,16 +702,17 @@ impl Value {
_ => false
}
}
pub fn is_int_reg(&self) -> bool {
pub fn is_reg(&self) -> bool {
match self.v {
Value_::SSAVar(_) => {
if is_scalar(&self.ty) && !is_fp(&self.ty) {
true
} else {
false
}
}
Value_::SSAVar(_) => true,
_ => false
}
}
pub fn is_const(&self) -> bool {
match self.v {
Value_::Constant(_) => true,
_ => false
}
}
......@@ -724,21 +725,6 @@ impl Value {
})
}
pub fn is_fp_reg(&self) -> bool {
match self.v {
Value_::SSAVar(_) => {
if is_scalar(&self.ty) && is_fp(&self.ty) {
true
} else {
false
}
},
Value_::Constant(Constant::Double(_)) => true,
Value_::Constant(Constant::Float(_)) => true,
_ => false
}
}
pub fn is_int_const(&self) -> bool {
match self.v {
Value_::Constant(Constant::Int(_)) => true,
......
......@@ -16,6 +16,7 @@ use runtime::entrypoints::RuntimeEntrypoint;
use compiler::CompilerPass;
use compiler::backend;
use compiler::backend::RegGroup;
use compiler::backend::PROLOGUE_BLOCK_NAME;
use compiler::backend::x86_64;
use compiler::backend::x86_64::CodeGenerator;
......@@ -601,7 +602,7 @@ impl <'a> InstructionSelection {
let mut status_value_index = 1;
// status flags only works with int operations
if values[0].is_int_reg() {
if RegGroup::get_from_value(&values[0]) == RegGroup::GPR {
// negative flag
if status.flag_n {
let tmp_status = values[status_value_index].clone();
......@@ -2206,7 +2207,7 @@ impl <'a> InstructionSelection {
// new block (no livein)
self.current_block = Some(slowpath.clone());
self.backend.start_block(slowpath.clone());
if size.is_int_reg() {
if RegGroup::get_from_value(&size) == RegGroup::GPR {
self.backend.set_block_livein(slowpath.clone(), &vec![size.clone()]);
}
......@@ -2466,7 +2467,9 @@ impl <'a> InstructionSelection {
let mut fpr_arg_count = 0;
for arg in args.iter() {
if arg.is_int_reg() {
let arg_reg_group = RegGroup::get_from_value(&arg);
if arg_reg_group == RegGroup::GPR && arg.is_reg() {
if gpr_arg_count < x86_64::ARGUMENT_GPRs.len() {
let arg_gpr = {
let ref reg64 = x86_64::ARGUMENT_GPRs[gpr_arg_count];
......@@ -2480,7 +2483,7 @@ impl <'a> InstructionSelection {
// use stack to pass argument
stack_args.push(arg.clone());
}
} else if arg.is_int_const() {
} else if arg_reg_group == RegGroup::GPR && arg.is_const() {
let int_const = arg.extract_int_const();
if gpr_arg_count < x86_64::ARGUMENT_GPRs.len() {
......@@ -2501,9 +2504,7 @@ impl <'a> InstructionSelection {
// use stack to pass argument
stack_args.push(arg.clone());
}
} else if arg.is_mem() {
unimplemented!()
} else if arg.is_fp_reg() {
} else if arg_reg_group == RegGroup::FPR && arg.is_reg() {
if fpr_arg_count < x86_64::ARGUMENT_FPRs.len() {
let arg_fpr = x86_64::ARGUMENT_FPRs[fpr_arg_count].clone();
......@@ -2513,7 +2514,7 @@ impl <'a> InstructionSelection {
stack_args.push(arg.clone());
}
} else {
// struct, etc
// fp const, struct, etc
unimplemented!()
}
}
......@@ -2601,7 +2602,7 @@ impl <'a> InstructionSelection {
}
};
if ret_val.is_int_reg() {
if RegGroup::get_from_value(&ret_val) == RegGroup::GPR && ret_val.is_reg() {
if gpr_ret_count < x86_64::RETURN_GPRs.len() {
let ret_gpr = {
let ref reg64 = x86_64::RETURN_GPRs[gpr_ret_count];
......@@ -2615,7 +2616,7 @@ impl <'a> InstructionSelection {
// get return value by stack
unimplemented!()
}
} else if ret_val.is_fp_reg() {
} else if RegGroup::get_from_value(&ret_val) == RegGroup::FPR && ret_val.is_reg() {
// floating point register
if fpr_ret_count < x86_64::RETURN_FPRs.len() {
let ref ret_fpr = x86_64::RETURN_FPRs[fpr_ret_count];
......@@ -2959,7 +2960,7 @@ impl <'a> InstructionSelection {
let mut arg_by_stack = vec![];
for arg in args {
if arg.is_int_reg() {
if RegGroup::get_from_value(&arg) == RegGroup::GPR && arg.is_reg() {
if gpr_arg_count < x86_64::ARGUMENT_GPRs.len() {
let arg_gpr = {
let ref reg64 = x86_64::ARGUMENT_GPRs[gpr_arg_count];
......@@ -2982,7 +2983,7 @@ impl <'a> InstructionSelection {
// let arg_size = vm.get_backend_type_info(arg.ty.id()).size;
// stack_arg_offset += arg_size as i32;
}
} else if arg.is_fp_reg() {
} else if RegGroup::get_from_value(&arg) == RegGroup::FPR && arg.is_reg() {
if fpr_arg_count < x86_64::ARGUMENT_FPRs.len() {
let arg_fpr = x86_64::ARGUMENT_FPRs[fpr_arg_count].clone();
......@@ -3210,7 +3211,7 @@ impl <'a> InstructionSelection {
let ref value = inst.value.as_ref().unwrap()[0];
if value.is_int_reg() {
if RegGroup::get_from_value(&value) == RegGroup::GPR && value.is_reg() {
true
} else {
false
......@@ -3221,7 +3222,7 @@ impl <'a> InstructionSelection {
}
TreeNode_::Value(ref pv) => {
pv.is_int_reg() || pv.is_int_const()
RegGroup::get_from_value(&pv) == RegGroup::GPR
}
}
}
......@@ -3236,7 +3237,7 @@ impl <'a> InstructionSelection {
let ref value = inst.value.as_ref().unwrap()[0];
if value.is_fp_reg() {
if RegGroup::get_from_value(&value) == RegGroup::FPR {
true
} else {
false
......@@ -3247,7 +3248,7 @@ impl <'a> InstructionSelection {
}
TreeNode_::Value(ref pv) => {
pv.is_fp_reg()
RegGroup::get_from_value(pv) == RegGroup::FPR
}
}
}
......@@ -3875,10 +3876,10 @@ impl <'a> InstructionSelection {
fn emit_move_node_to_value(&mut self, dest: &P<Value>, src: &TreeNode, f_content: &FunctionContent, f_context: &mut FunctionContext, vm: &VM) {
let ref dst_ty = dest.ty;
if !types::is_fp(dst_ty) && types::is_scalar(dst_ty) {
if RegGroup::get_from_ty(&dst_ty) == RegGroup::GPR {
if self.match_iimm(src) {
let (src_imm, src_len) = self.node_iimm_to_i32_with_len(src);
if dest.is_int_reg() {
if RegGroup::get_from_value(&dest) == RegGroup::GPR && dest.is_reg() {
self.backend.emit_mov_r_imm(dest, src_imm);
} else if dest.is_mem() {
self.backend.emit_mov_mem_imm(dest, src_imm, src_len);
......@@ -3891,7 +3892,7 @@ impl <'a> InstructionSelection {
} else {
panic!("expected src: {}", src);
}
} else if types::is_fp(dst_ty) && types::is_scalar(dst_ty) {
} else if RegGroup::get_from_ty(&dst_ty) == RegGroup::FPR {
if self.match_fpreg(src) {
let src_reg = self.emit_fpreg(src, f_content, f_context, vm);
self.emit_move_value_to_value(dest, &src_reg)
......@@ -3911,43 +3912,45 @@ impl <'a> InstructionSelection {
debug!("source type: {}", src_ty);
debug!("dest type: {}", dest.ty);
if types::is_scalar(src_ty) && !types::is_fp(src_ty) {
if RegGroup::get_from_ty(&src_ty) == RegGroup::GPR {
// gpr mov
if dest.is_int_reg() && src.is_int_reg() {
if dest.is_reg() && src.is_reg() {
self.backend.emit_mov_r_r(dest, src);
} else if dest.is_int_reg() && src.is_mem() {
} else if dest.is_reg() && src.is_mem() {
self.backend.emit_mov_r_mem(dest, src);
} else if dest.is_int_reg() && src.is_int_const() {
} else if dest.is_reg() && src.is_const() {
let imm = self.value_iimm_to_i32(src);
self.backend.emit_mov_r_imm(dest, imm);
} else if dest.is_mem() && src.is_int_reg() {
} else if dest.is_mem() && src.is_reg() {
self.backend.emit_mov_mem_r(dest, src);
} else if dest.is_mem() && src.is_int_const() {
} else if dest.is_mem() && src.is_const() {
let (imm, len) = self.value_iimm_to_i32_with_len(src);
self.backend.emit_mov_mem_imm(dest, imm, len);
} else {
panic!("unexpected gpr mov between {} -> {}", src, dest);
}
} else if types::is_scalar(src_ty) && types::is_fp(src_ty) {
} else if RegGroup::get_from_ty(&src_ty) == RegGroup::GPREX {
unimplemented!()
} else if RegGroup::get_from_ty(&src_ty) == RegGroup::FPR {
// fpr mov
match src_ty.v {
MuType_::Double => {
if dest.is_fp_reg() && src.is_fp_reg() {
if dest.is_reg() && src.is_reg() {
self.backend.emit_movsd_f64_f64(dest, src);
} else if dest.is_fp_reg() && src.is_mem() {
} else if dest.is_reg() && src.is_mem() {
self.backend.emit_movsd_f64_mem64(dest, src);
} else if dest.is_mem() && src.is_fp_reg() {
} else if dest.is_mem() && src.is_reg() {
self.backend.emit_movsd_mem64_f64(dest, src);
} else {
panic!("unexpected fpr mov between {} -> {}", src, dest);
}
}
MuType_::Float => {
if dest.is_fp_reg() && src.is_fp_reg() {
if dest.is_reg() && src.is_reg() {
self.backend.emit_movss_f32_f32(dest, src);
} else if dest.is_fp_reg() && src.is_mem() {
} else if dest.is_reg() && src.is_mem() {
self.backend.emit_movss_f32_mem32(dest, src);
} else if dest.is_mem() && src.is_fp_reg() {
} else if dest.is_mem() && src.is_reg() {
self.backend.emit_movss_mem32_f32(dest, src);
} else {
panic!("unexpected fpr mov between {} -> {}", src, dest);
......
......@@ -425,8 +425,9 @@ pub fn init_machine_regs_for_func (func_context: &mut FunctionContext) {
pub fn number_of_regs_in_group(group: RegGroup) -> usize {
match group {
RegGroup::GPR => ALL_GPRs.len(),
RegGroup::FPR => ALL_FPRs.len()
RegGroup::GPR => ALL_GPRs.len(),
RegGroup::GPREX => ALL_GPRs.len(),
RegGroup::FPR => ALL_FPRs.len()
}
}
......@@ -444,13 +445,7 @@ pub fn all_usable_regs() -> &'static Vec<P<Value>> {
pub fn pick_group_for_reg(reg_id: MuID) -> RegGroup {
let reg = all_regs().get(&reg_id).unwrap();
if reg.is_int_reg() {
RegGroup::GPR
} else if reg.is_fp_reg() {
RegGroup::FPR
} else {
panic!("expect a machine reg to be either a GPR or a FPR: {}", reg)
}
RegGroup::get_from_value(reg)
}
pub fn is_callee_saved(reg_id: MuID) -> bool {
......
......@@ -315,10 +315,10 @@ impl fmt::Display for BackendTypeInfo {
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub enum RegGroup {GPR, FPR}
pub enum RegGroup {GPR, GPREX, FPR}
impl RegGroup {
pub fn get(ty: &P<MuType>) -> RegGroup {
pub fn get_from_ty(ty: &P<MuType>) -> RegGroup {
match ty.v {
// for now, only use 64bits registers
MuType_::Int(len) if len == 1 => RegGroup::GPR,
......@@ -326,6 +326,7 @@ impl RegGroup {
MuType_::Int(len) if len == 16 => RegGroup::GPR,
MuType_::Int(len) if len == 32 => RegGroup::GPR,
MuType_::Int(len) if len == 64 => RegGroup::GPR,
MuType_::Int(len) if len == 128=> RegGroup::GPREX,
MuType_::Ref(_)
| MuType_::IRef(_)
......@@ -343,4 +344,8 @@ impl RegGroup {
_ => unimplemented!()
}
}
pub fn get_from_value(val: &P<Value>) -> RegGroup {
RegGroup::get_from_ty(&val.ty)
}
}
......@@ -43,7 +43,7 @@ impl InterferenceGraph {
let node = GraphNode {
temp: reg_id,
color: None,
group: backend::RegGroup::get(entry.ty()),
group: backend::RegGroup::get_from_ty(entry.ty()),
spill_cost: 0.0f32
};
......
......@@ -120,6 +120,7 @@ impl MuStack {
match reg_group {
RegGroup::GPR => gpr_used.push(word),
RegGroup::GPREX => unimplemented!(),
RegGroup::FPR => fpr_used.push(word),
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment