mirror of
https://github.com/open-goal/jak-project.git
synced 2024-11-23 22:29:53 +00:00
add sqrt (#270)
This commit is contained in:
parent
cdce4d9612
commit
1b5b9a2469
@ -434,6 +434,7 @@ class Compiler {
|
||||
Val* compile_pointer_add(const goos::Object& form, const goos::Object& rest, Env* env);
|
||||
Val* compile_fmin(const goos::Object& form, const goos::Object& rest, Env* env);
|
||||
Val* compile_fmax(const goos::Object& form, const goos::Object& rest, Env* env);
|
||||
Val* compile_sqrtf(const goos::Object& form, const goos::Object& rest, Env* env);
|
||||
|
||||
// Function
|
||||
Val* compile_lambda(const goos::Object& form, const goos::Object& rest, Env* env);
|
||||
|
@ -618,6 +618,8 @@ std::string IR_FloatMath::print() {
|
||||
return fmt::format("maxss {}, {}", m_dest->print(), m_arg->print());
|
||||
case FloatMathKind::MIN_SS:
|
||||
return fmt::format("minss {}, {}", m_dest->print(), m_arg->print());
|
||||
case FloatMathKind::SQRT_SS:
|
||||
return fmt::format("sqrtss {}, {}", m_dest->print(), m_arg->print());
|
||||
default:
|
||||
throw std::runtime_error("Unsupported FloatMathKind");
|
||||
}
|
||||
@ -626,7 +628,9 @@ std::string IR_FloatMath::print() {
|
||||
RegAllocInstr IR_FloatMath::to_rai() {
|
||||
RegAllocInstr rai;
|
||||
rai.write.push_back(m_dest->ireg());
|
||||
rai.read.push_back(m_dest->ireg());
|
||||
if (m_kind != FloatMathKind::SQRT_SS) {
|
||||
rai.read.push_back(m_dest->ireg());
|
||||
}
|
||||
rai.read.push_back(m_arg->ireg());
|
||||
return rai;
|
||||
}
|
||||
@ -659,6 +663,10 @@ void IR_FloatMath::do_codegen(emitter::ObjectGenerator* gen,
|
||||
gen->add_instr(
|
||||
IGen::minss_xmm_xmm(get_reg(m_dest, allocs, irec), get_reg(m_arg, allocs, irec)), irec);
|
||||
break;
|
||||
case FloatMathKind::SQRT_SS:
|
||||
gen->add_instr(IGen::sqrts_xmm(get_reg(m_dest, allocs, irec), get_reg(m_arg, allocs, irec)),
|
||||
irec);
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
|
@ -212,7 +212,7 @@ class IR_IntegerMath : public IR {
|
||||
u8 m_shift_amount = 0;
|
||||
};
|
||||
|
||||
enum class FloatMathKind { DIV_SS, MUL_SS, ADD_SS, SUB_SS, MIN_SS, MAX_SS };
|
||||
enum class FloatMathKind { DIV_SS, MUL_SS, ADD_SS, SUB_SS, MIN_SS, MAX_SS, SQRT_SS };
|
||||
|
||||
class IR_FloatMath : public IR {
|
||||
public:
|
||||
|
@ -328,7 +328,7 @@ Val* Compiler::compile_asm_svf(const goos::Object& form, const goos::Object& res
|
||||
}
|
||||
|
||||
void Compiler::check_vector_float_regs(const goos::Object& form,
|
||||
Env* env,
|
||||
Env*,
|
||||
std::vector<std::pair<std::string, RegVal*>> args) {
|
||||
for (std::pair<std::string, RegVal*> arg : args) {
|
||||
if (!arg.second->settable() || arg.second->ireg().reg_class != RegClass::VECTOR_FLOAT) {
|
||||
@ -791,6 +791,9 @@ emitter::Register::VF_ELEMENT Compiler::ftf_fsf_to_vector_element(u8 val) {
|
||||
return emitter::Register::VF_ELEMENT::Z;
|
||||
case 0b11:
|
||||
return emitter::Register::VF_ELEMENT::W;
|
||||
default:
|
||||
throw_compiler_error_no_code("Invalid vector element {}", (int)val);
|
||||
return emitter::Register::VF_ELEMENT::NONE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -194,6 +194,7 @@ static const std::unordered_map<
|
||||
{"&+", &Compiler::compile_pointer_add},
|
||||
{"fmax", &Compiler::compile_fmax},
|
||||
{"fmin", &Compiler::compile_fmin},
|
||||
{"sqrtf", &Compiler::compile_sqrtf},
|
||||
|
||||
// BUILDER (build-dgo/build-cgo?)
|
||||
{"build-dgos", &Compiler::compile_build_dgo},
|
||||
|
@ -245,6 +245,19 @@ Val* Compiler::compile_fmax(const goos::Object& form, const goos::Object& rest,
|
||||
return result;
|
||||
}
|
||||
|
||||
Val* Compiler::compile_sqrtf(const goos::Object& form, const goos::Object& rest, Env* env) {
|
||||
auto args = get_va(form, rest);
|
||||
va_check(form, args, {{}}, {});
|
||||
|
||||
auto first_val = compile_error_guard(args.unnamed.at(0), env);
|
||||
if (get_math_mode(first_val->type()) != MATH_FLOAT) {
|
||||
throw_compiler_error(form, "Must use a float for sqrtf");
|
||||
}
|
||||
auto result = env->make_fpr(first_val->type());
|
||||
env->emit_ir<IR_FloatMath>(FloatMathKind::SQRT_SS, result, first_val->to_fpr(env));
|
||||
return result;
|
||||
}
|
||||
|
||||
Val* Compiler::compile_imul64(const goos::Object& form, const goos::Object& rest, Env* env) {
|
||||
auto args = get_va(form, rest);
|
||||
if (!args.named.empty() || args.unnamed.empty()) {
|
||||
|
@ -1897,6 +1897,17 @@ class IGen {
|
||||
return instr;
|
||||
}
|
||||
|
||||
static Instruction sqrts_xmm(Register dst, Register src) {
|
||||
assert(dst.is_xmm());
|
||||
assert(src.is_xmm());
|
||||
Instruction instr(0xf3);
|
||||
instr.set_op2(0x0f);
|
||||
instr.set_op3(0x51);
|
||||
instr.set_modrm_and_rex(dst.hw_id(), src.hw_id(), 3, false);
|
||||
instr.swap_op0_rex();
|
||||
return instr;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Multiply two floats in xmm's
|
||||
*/
|
||||
|
2
test/goalc/source_templates/with_game/sqrtf.gc
Normal file
2
test/goalc/source_templates/with_game/sqrtf.gc
Normal file
@ -0,0 +1,2 @@
|
||||
(format #t "~f~%" (sqrtf 5.0))
|
||||
0
|
@ -321,6 +321,10 @@ TEST_F(WithGameTests, Math) {
|
||||
runner.run_static_test(env, testCategory, "test-math.gc", get_test_pass_string("math", 31));
|
||||
}
|
||||
|
||||
TEST_F(WithGameTests, Sqrtf) {
|
||||
runner.run_static_test(env, testCategory, "sqrtf.gc", {"2.2360\n0\n"});
|
||||
}
|
||||
|
||||
TEST_F(WithGameTests, StaticPairs) {
|
||||
runner.run_static_test(env, testCategory, "test-static-pair-1.gc",
|
||||
{"(1 (w . a) beans 2 (-1 -2) twelve (a . \"test\"))\n0\n"});
|
||||
@ -425,7 +429,7 @@ struct VectorFloatRegister {
|
||||
std::regex("nan|inf|-nan|-inf"), "NaN");
|
||||
}
|
||||
|
||||
std::string toGOALFormat(float val) {
|
||||
std::string toGOALFormat(float) {
|
||||
std::string answer = fmt::format("{:.4f}", x);
|
||||
// {fmt} formats negative 0 as "-0.000", just going to flip any negative zeros to positives as I
|
||||
// don't think is an OpenGOAL issue
|
||||
|
@ -3889,3 +3889,13 @@ TEST(EmitterXMM, StackStoreFull8) {
|
||||
tester.emit(IGen::store128_gpr64_xmm128_s8(RSP, XMM0 + 13, -12));
|
||||
EXPECT_EQ(tester.dump_to_hex_string(true), "660F7F5C24F466440F7F6C24F4");
|
||||
}
|
||||
|
||||
TEST(EmitterXMM, SqrtS) {
|
||||
CodeTester tester;
|
||||
tester.init_code_buffer(1024);
|
||||
tester.emit(IGen::sqrts_xmm(XMM0 + 1, XMM0 + 2));
|
||||
tester.emit(IGen::sqrts_xmm(XMM0 + 11, XMM0 + 2));
|
||||
tester.emit(IGen::sqrts_xmm(XMM0 + 1, XMM0 + 12));
|
||||
tester.emit(IGen::sqrts_xmm(XMM0 + 11, XMM0 + 12));
|
||||
EXPECT_EQ(tester.dump_to_hex_string(true), "F30F51CAF3440F51DAF3410F51CCF3450F51DC");
|
||||
}
|
Loading…
Reference in New Issue
Block a user