Commit d84ffada authored by qinsoon's avatar qinsoon

fix. float type should work now

parent 364ece82
Pipeline #407 failed with stage
in 77 minutes and 22 seconds
......@@ -2158,6 +2158,10 @@ impl CodeGenerator for ASMCodeGen {
self.internal_binop_no_def_mem_r("cmp", op1, op2)
}
fn emit_test_r_r(&mut self, op1: &P<Value>, op2: &P<Value>) {
self.internal_binop_no_def_r_r("test", op1, op2)
}
// mov
fn emit_mov_r64_imm64 (&mut self, dest: &P<Value>, src: i64) {
......@@ -2869,7 +2873,14 @@ impl CodeGenerator for ASMCodeGen {
let asm = format!("jle {}", symbol(self.mangle_block_label(dest_name.clone())));
self.add_asm_branch2(asm, dest_name);
}
}
fn emit_js(&mut self, dest_name: MuName) {
trace!("emit: js {}", dest_name);
let asm = format!("js {}", symbol(self.mangle_block_label(dest_name.clone())));
self.add_asm_branch2(asm, dest_name);
}
#[cfg(target_os = "macos")]
fn emit_call_near_rel32(&mut self, callsite: String, func: MuName, pe: Option<MuName>) -> ValueLocation {
......@@ -2996,6 +3007,9 @@ impl CodeGenerator for ASMCodeGen {
fn emit_movsd_f64_f64 (&mut self, dest: &P<Value>, src: &P<Value>) {
self.internal_fp_mov_f_f("movsd", dest, src)
}
fn emit_movapd_f64_f64 (&mut self, dest: Reg, src: Reg) {
self.internal_fp_mov_f_f("movapd", dest, src);
}
// load
fn emit_movsd_f64_mem64(&mut self, dest: &P<Value>, src: &P<Value>) {
self.internal_fp_mov_f_mem("movsd", dest, src, false)
......@@ -3010,6 +3024,9 @@ impl CodeGenerator for ASMCodeGen {
fn emit_movss_f32_f32 (&mut self, dest: &P<Value>, src: &P<Value>) {
self.internal_fp_mov_f_f("movss", dest, src)
}
fn emit_movaps_f32_f32 (&mut self, dest: Reg, src: Reg) {
self.internal_fp_mov_f_f("movaps", dest, src);
}
// load
fn emit_movss_f32_mem32(&mut self, dest: &P<Value>, src: &P<Value>) {
self.internal_fp_mov_f_mem("movss", dest, src, false)
......@@ -3117,6 +3134,9 @@ impl CodeGenerator for ASMCodeGen {
fn emit_cvtsd2si_r_f64 (&mut self, dest: Reg, src: Reg) {
self.internal_fpr_to_gpr("cvtsd2si", dest, src);
}
fn emit_cvttsd2si_r_f64 (&mut self, dest: Reg, src: Reg) {
self.internal_fpr_to_gpr("cvttsd2si", dest, src);
}
// convert - single
......@@ -3126,6 +3146,9 @@ impl CodeGenerator for ASMCodeGen {
fn emit_cvtss2si_r_f32 (&mut self, dest: Reg, src: Reg) {
self.internal_fpr_to_gpr("cvtss2si", dest, src);
}
fn emit_cvttss2si_r_f32 (&mut self, dest: Reg, src: Reg) {
self.internal_fpr_to_gpr("cvttss2si", dest, src);
}
// unpack low data - interleave low byte
fn emit_punpckldq_f64_mem128(&mut self, dest: Reg, src: Mem) {
......@@ -3217,48 +3240,6 @@ impl CodeGenerator for ASMCodeGen {
true
)
}
fn emit_movapd_f64_f64 (&mut self, dest: Reg, src: Reg) {
trace!("emit movapd {} -> {}", src, dest);
let (reg1, id1, loc1) = self.prepare_fpreg(src, 6 + 1);
let (reg2, id2, loc2) = self.prepare_fpreg(dest, 6 + 1 + reg1.len() + 1);
let asm = format!("movapd {},{}", reg1, reg2);
self.add_asm_inst(
asm,
linked_hashmap!{
id2 => vec![loc2.clone()]
},
linked_hashmap!{
id1 => vec![loc1.clone()]
},
false
)
}
fn emit_cvttsd2si_r_f64 (&mut self, dest: Reg, src: Reg) {
let len = check_op_len(dest);
let inst = "cvttsd2si".to_string() + &op_postfix(len);
trace!("emit: {} {} -> {}", inst, src, dest);
let (reg1, id1, loc1) = self.prepare_fpreg(src, inst.len() + 1);
let (reg2, id2, loc2) = self.prepare_reg (dest, inst.len() + 1 + reg1.len() + 1);
let asm = format!("{} {},{}", inst, reg1, reg2);
self.add_asm_inst(
asm,
linked_hashmap!{
id2 => vec![loc2]
},
linked_hashmap!{
id1 => vec![loc1]
},
false
)
}
}
use compiler::backend::code_emission::create_emit_directory;
......
......@@ -39,6 +39,8 @@ pub trait CodeGenerator {
fn emit_cmp_imm_r(&mut self, op1: i32, op2: Reg);
fn emit_cmp_mem_r(&mut self, op1: Reg, op2: Reg);
fn emit_test_r_r (&mut self, op1: Reg, op2: Reg);
// gpr move
// mov imm64 to r64
......@@ -172,6 +174,8 @@ pub trait CodeGenerator {
fn emit_jge(&mut self, dest: MuName);
fn emit_jl(&mut self, dest: MuName);
fn emit_jle(&mut self, dest: MuName);
fn emit_js(&mut self, dest: MuName);
fn emit_call_near_rel32(&mut self, callsite: String, func: MuName, pe: Option<MuName>) -> ValueLocation;
fn emit_call_near_r64 (&mut self, callsite: String, func: &P<Value>, pe: Option<MuName>) -> ValueLocation;
......@@ -237,6 +241,7 @@ pub trait CodeGenerator {
// used for unsigned int to fp conversion
fn emit_cvttsd2si_r_f64 (&mut self, dest: Reg, src: Reg);
fn emit_cvttss2si_r_f32 (&mut self, dest: Reg, src: Reg);
// unpack low data - interleave low byte
fn emit_punpckldq_f64_mem128(&mut self, dest: Reg, src: Mem);
......@@ -248,4 +253,6 @@ pub trait CodeGenerator {
// move aligned packed double-precision fp values
fn emit_movapd_f64_mem128(&mut self, dest: Reg, src: Mem);
fn emit_movapd_f64_f64 (&mut self, dest: Reg, src: Mem);
fn emit_movaps_f32_f32 (&mut self, dest: Reg, src: Reg);
}
......@@ -67,11 +67,11 @@ fn test_float_add() {
let lib = testutil::compile_fnc("float_add", &float_add);
unsafe {
let float_add : libloading::Symbol<unsafe extern fn(f64, f64) -> f64> = lib.get(b"float_add").unwrap();
let float_add : libloading::Symbol<unsafe extern fn(f32, f32) -> f32> = lib.get(b"float_add").unwrap();
let float_add_1_1 = float_add(1f64, 1f64);
let float_add_1_1 = float_add(1f32, 1f32);
println!("float_add(1, 1) = {}", float_add_1_1);
assert!(float_add_1_1 == 2f64);
assert!(float_add_1_1 == 2f32);
}
}
......@@ -318,6 +318,55 @@ fn ui64tofp() -> VM {
vm
}
#[test]
fn test_ui64tofp_float() {
let lib = testutil::compile_fnc("ui64tofp_float", &ui64tofp_float);
unsafe {
let ui64tofp_float : libloading::Symbol<unsafe extern fn(u64) -> f32> = lib.get(b"ui64tofp_float").unwrap();
let res = ui64tofp_float(0u64);
println!("ui64tofp_float(0) = {}", res);
assert!(res == 0f32);
let res = ui64tofp_float(1u64);
println!("ui64tofp_float(1) = {}", res);
assert!(res == 1f32);
}
}
fn ui64tofp_float() -> VM {
let vm = VM::new();
typedef! ((vm) int64 = mu_int(64));
typedef! ((vm) float = mu_float);
funcsig! ((vm) sig = (int64) -> (float));
funcdecl! ((vm) <sig> ui64tofp_float);
funcdef! ((vm) <sig> ui64tofp_float VERSION ui64tofp_float_v1);
// blk entry
block! ((vm, ui64tofp_float_v1) blk_entry);
ssa! ((vm, ui64tofp_float_v1) <int64> x);
ssa! ((vm, ui64tofp_float_v1) <float> res);
inst! ((vm, ui64tofp_float_v1) blk_entry_conv:
res = CONVOP (ConvOp::UITOFP) <int64 float> x
);
inst! ((vm, ui64tofp_float_v1) blk_entry_ret:
RET (res)
);
define_block!((vm, ui64tofp_float_v1) blk_entry(x){
blk_entry_conv, blk_entry_ret
});
define_func_ver!((vm) ui64tofp_float_v1 (entry: blk_entry) {blk_entry});
vm
}
#[test]
fn test_ui32tofp() {
let lib = testutil::compile_fnc("ui32tofp", &ui32tofp);
......
......@@ -1405,7 +1405,7 @@ def test_float():
assert res.returncode == 0, res.err
assert res.out == '(0.893876, 1.000000, 0.447179)\n'
@pytest.mark.xfail(reason='int128 not implemented')
@may_spawn_proc
def test_RPySOM():
from som.vm.universe import main, Exit
......
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