This commit is contained in:
water111 2021-02-17 00:57:21 -05:00 committed by GitHub
parent cdce4d9612
commit 1b5b9a2469
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 57 additions and 4 deletions

View File

@ -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);

View File

@ -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);
}

View File

@ -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:

View File

@ -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;
}
}

View File

@ -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},

View File

@ -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()) {

View File

@ -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
*/

View File

@ -0,0 +1,2 @@
(format #t "~f~%" (sqrtf 5.0))
0

View File

@ -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

View File

@ -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");
}