diff --git a/source/m3_compile.c b/source/m3_compile.c index 33f828e..c3733bf 100644 --- a/source/m3_compile.c +++ b/source/m3_compile.c @@ -1132,22 +1132,22 @@ _ (Compile_ElseBlock (o, pc, blockType)); } _catch: return result; } +static const IM3Operation ops_Select_i [] = { op_Select_i_ssr, op_Select_i_srs, op_Select_i_rss, op_Select_i_sss }; +static const IM3Operation ops_Select_f [] = { op_Select_f_ssr, op_Select_f_srs, op_Select_f_rss, op_Select_f_sss }; M3Result Compile_Select (IM3Compilation o, u8 i_opcode) { M3Result result = c_m3Err_none; - IM3Operation ops [] = { op_Select_i_ssr, op_Select_i_srs, op_Select_i_rss }; - u16 slots [3] = { 0xffff, 0xffff, 0xffff }; - IM3Operation op = op_Select_i_sss; + int opIdx = 3; // op_Select_*_sss u8 type = 0; for (u32 i = 0; i < 3; i++) { if (IsStackTopInRegister (o)) - op = ops [i]; + opIdx = i; else slots [i] = GetStackTopExecSlot (o); @@ -1155,13 +1155,17 @@ M3Result Compile_Select (IM3Compilation o, u8 i_opcode) _ (Pop (o)); } - d_m3AssertFatal (IsIntType (type)); // TODO: fp unimplemented - // this operation doesn't consume a register, so might have to protected its contents - if (op == op_Select_i_sss) + if (opIdx == 3) { _ (PreserveRegisterIfOccupied (o, type)); + } + + if (IsIntType (type)) { +_ (EmitOp (o, ops_Select_i[opIdx])); + } else { +_ (EmitOp (o, ops_Select_f[opIdx])); + } -_ (EmitOp (o, op)); for (u32 i = 0; i < 3; i++) { diff --git a/source/m3_exec.h b/source/m3_exec.h index bdcd3b9..05f46a8 100644 --- a/source/m3_exec.h +++ b/source/m3_exec.h @@ -414,19 +414,55 @@ d_m3Op (Select_i_sss) return nextOp (); } - -d_m3Op (Select_f) +d_m3Op (Select_f_ssr) { i32 condition = (i32) _r0; - f64 operand2 = * (f64 *) (_sp + immediate (i32)); - f64 operand1 = * (f64 *) (_sp + immediate (i32)); + f64 operand2 = * (f64*)(_sp + immediate (i32)); + f64 operand1 = * (f64*)(_sp + immediate (i32)); _fp0 = (condition) ? operand1 : operand2; return nextOp (); } +d_m3Op (Select_f_srs) +{ + i32 condition = (i32) * (_sp + immediate (i32)); + + f64 operand2 = _fp0; + f64 operand1 = * (f64*)(_sp + immediate (i32)); + + _fp0 = (condition) ? operand1 : operand2; + + return nextOp (); +} + + +d_m3Op (Select_f_rss) +{ + i32 condition = (i32) * (_sp + immediate (i32)); + + f64 operand2 = * (f64*)(_sp + immediate (i32)); + f64 operand1 = _fp0; + + _fp0 = (condition) ? operand1 : operand2; + + return nextOp (); +} + + +d_m3Op (Select_f_sss) +{ + i32 condition = (i32) * (_sp + immediate (i32)); + + f64 operand2 = * (f64*)(_sp + immediate (i32)); + f64 operand1 = * (f64*)(_sp + immediate (i32)); + + _fp0 = (condition) ? operand1 : operand2; + + return nextOp (); +} d_m3Op (Return) { diff --git a/test/run-spec-test.py b/test/run-spec-test.py index 2ef970e..4edfbc2 100755 --- a/test/run-spec-test.py +++ b/test/run-spec-test.py @@ -303,13 +303,13 @@ else: "conversions", "stack", "fac", "call", "call_indirect", + "left-to-right", "break-drop", "forward", "func_ptrs", "endianness", #--- Almost ready --- - #"left-to-right", -> need to implement float select #"int_literals", -> stack underflow #"memory_trap", "address", -> init memory size + track memory bounds #"float_memory",