Merge pull request #756 from water111/w/u64-float-set

[goalc] support storing a float in a 64-bit memory location
This commit is contained in:
water111 2021-08-12 20:30:27 -04:00 committed by GitHub
commit 222ea5da27
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 24 additions and 1 deletions

View File

@ -187,4 +187,5 @@
- Creating arrays on the stack now must be done with `stack-no-clear` as they are not memset to 0 or constructed in any way.
- The register allocator has been dramatically improved and generates ~5x fewer spill instructions and is able to eliminate more moves.
- Added a `(print-debug-compiler-stats)` form to print out statistics related to register allocation and move elimination
- Added `get-enum-vals` which returns a list of pairs. Each pair is the name (symbol) and value (int) for each value in the enum
- Added `get-enum-vals` which returns a list of pairs. Each pair is the name (symbol) and value (int) for each value in the enum
- It is now possible to set a 64-bit memory location from a float, if you insert a cast. It will zero-extend the float, just like any other float -> 64-bit conversion.

View File

@ -226,6 +226,7 @@ Val* Compiler::do_set(const goos::Object& form, Val* dest, RegVal* src_in_reg, V
src_in_reg = src_128;
}
// we want to allow setting a smaller thing from a 128-bit variable
if (as_mem_deref->info.size != 16 && (src_in_reg->ireg().reg_class == RegClass::VECTOR_FLOAT ||
src_in_reg->ireg().reg_class == RegClass::INT_128)) {
auto fe = get_parent_env_of_type<FunctionEnv>(env);
@ -234,6 +235,14 @@ Val* Compiler::do_set(const goos::Object& form, Val* dest, RegVal* src_in_reg, V
src_in_reg = src_gpr;
}
// we want to allow setting a 64-bit place to a float
if (as_mem_deref->info.size == 8 && src_in_reg->ireg().reg_class == RegClass::FLOAT) {
auto fe = get_parent_env_of_type<FunctionEnv>(env);
auto src_gpr = fe->make_ireg(src_in_reg->type(), RegClass::GPR_64);
env->emit_ir<IR_RegSet>(src_gpr, src_in_reg);
src_in_reg = src_gpr;
}
// setting somewhere in memory
auto base = as_mem_deref->base;
auto base_as_mco = dynamic_cast<MemoryOffsetConstantVal*>(base);

View File

@ -0,0 +1,8 @@
(let ((a (new 'stack-no-clear 'array 'float 4))
(b (new 'stack-no-clear 'array 'uint64 2))
)
(set! (-> b 0) #xbbbbbbbbbbbbbbbb)
(set! (-> a 0) 12.0)
(set! (-> b 0) (the-as uint (- (-> a 0))))
(format #t "~f #x~X #x~X #x~X~%" (-> b 0) (-> b 0) (-> (the-as (pointer uint32) b) 0) (-> (the-as (pointer uint32) b) 1))
)

View File

@ -830,6 +830,11 @@ TEST_F(WithGameTests, GetEnumVals) {
"(thing5 . #<invalid object #x5>))\n0\n"});
}
TEST_F(WithGameTests, SetU64FromFloat) {
runner.run_static_test(env, testCategory, "test-set-u64-from-float.gc",
{"-12.0000 #xc1400000 #xc1400000 #x0\n0\n"});
}
TEST(TypeConsistency, TypeConsistency) {
Compiler compiler;
compiler.enable_throw_on_redefines();