Browse Source

Add support for some of the new opcodes for x86.

Add tests for integer/float conversions.
cache-refactoring
Klaus Treichel 14 years ago
parent
commit
c4f149eb86
  1. 13
      ChangeLog
  2. 87
      jit/jit-rules-x86.ins
  3. 148
      tests/math.pas

13
ChangeLog

@ -1,3 +1,16 @@
2010-08-08 Klaus Treichel <ktreichel@web.de>
* jit/jit-rules-x86.ins (JIT_OP_FLOAT32_TO_INT,
JIT_OP_FLOAT64_TO_INT, JIT_OP_FLOAT32_TO_LONG,
JIT_OP_FLOAT64_TO_LONG, JIT_OP_INT_TO_FLOAT32,
JIT_OP_INT_TO_FLOAT64, JIT_OP_UINT_TO_FLOAT32,
JIT_OP_UINT_TO_FLOAT64, JIT_OP_LONG_TO_FLOAT32,
JIT_OP_LONG_TO_FLOAT64, JIT_OP_ULONG_TO_FLOAT32,
JIT_OP_ULONG_TO_FLOAT64, JIT_OP_FLOAT64_TO_FLOAT32,
JIT_OP_FLOAT32_TO_FLOAT64: Add support for these new opcodes.
* tests/math.pas: Add tests for integer/float conversions.
2010-08-07 Klaus Treichel <ktreichel@web.de>
* config/jit-opcodes.ops: Add opcodes for direct conversions from

87
jit/jit-rules-x86.ins

@ -143,7 +143,7 @@ JIT_OP_EXPAND_UINT:
x86_clear_reg(inst, %1);
}
JIT_OP_NFLOAT_TO_INT: stack
JIT_OP_FLOAT32_TO_INT, JIT_OP_FLOAT64_TO_INT, JIT_OP_NFLOAT_TO_INT: stack
[=reg, freg] -> {
/* allocate space on the stack for 2 shorts and 1 int */
x86_alu_reg_imm(inst, X86_SUB, X86_ESP, 8);
@ -164,7 +164,7 @@ JIT_OP_NFLOAT_TO_INT: stack
x86_alu_reg_imm(inst, X86_ADD, X86_ESP, 8);
}
JIT_OP_NFLOAT_TO_LONG: stack
JIT_OP_FLOAT32_TO_LONG, JIT_OP_FLOAT64_TO_LONG, JIT_OP_NFLOAT_TO_LONG: stack
[=lreg, freg] -> {
/* allocate space on the stack for 2 shorts and 1 long */
x86_alu_reg_imm(inst, X86_SUB, X86_ESP, 12);
@ -186,22 +186,83 @@ JIT_OP_NFLOAT_TO_LONG: stack
x86_alu_reg_imm(inst, X86_ADD, X86_ESP, 12);
}
JIT_OP_INT_TO_NFLOAT:
JIT_OP_INT_TO_FLOAT32:
[=freg, local] -> {
x86_alu_reg_imm(inst, X86_SUB, X86_ESP, sizeof(void *));
x86_fild_membase(inst, X86_EBP, $2, 0);
x86_fst_membase(inst, X86_ESP, 0, 0, 1);
x86_fld_membase(inst, X86_ESP, 0, 0);
x86_alu_reg_imm(inst, X86_ADD, X86_ESP, sizeof(void *));
}
[=freg, reg] -> {
x86_push_reg(inst, $2);
x86_fild_membase(inst, X86_ESP, 0, 0);
x86_fst_membase(inst, X86_ESP, 0, 0, 1);
x86_fld_membase(inst, X86_ESP, 0, 0);
x86_alu_reg_imm(inst, X86_ADD, X86_ESP, sizeof(jit_nint));
}
JIT_OP_UINT_TO_NFLOAT:
JIT_OP_INT_TO_FLOAT64, JIT_OP_INT_TO_NFLOAT:
[=freg, local] -> {
x86_fild_membase(inst, X86_EBP, $2, 0);
}
[=freg, reg] -> {
x86_push_reg(inst, $2);
x86_fild_membase(inst, X86_ESP, 0, 0);
x86_alu_reg_imm(inst, X86_ADD, X86_ESP, sizeof(jit_nint));
}
JIT_OP_UINT_TO_FLOAT32:
[=freg, reg, scratch reg] -> {
x86_clear_reg(inst, $3);
x86_push_reg(inst, $3);
x86_push_reg(inst, $2);
x86_fild_membase(inst, X86_ESP, 0, 1);
x86_fst_membase(inst, X86_ESP, 0, 0, 1);
x86_fld_membase(inst, X86_ESP, 0, 0);
x86_alu_reg_imm(inst, X86_ADD, X86_ESP, sizeof(jit_long));
}
JIT_OP_UINT_TO_FLOAT64, JIT_OP_UINT_TO_NFLOAT:
[=freg, reg, scratch reg] -> {
x86_clear_reg(inst, $3);
x86_push_reg(inst, $3);
x86_push_reg(inst, $2);
x86_fild_membase(inst, X86_ESP, 0, 1);
x86_alu_reg_imm(inst, X86_ADD, X86_ESP, sizeof(jit_long));
}
JIT_OP_LONG_TO_FLOAT32:
[=freg, local] -> {
x86_alu_reg_imm(inst, X86_SUB, X86_ESP, sizeof(jit_float32));
x86_fild_membase(inst, X86_EBP, $2, 1);
x86_fst_membase(inst, X86_ESP, 0, 0, 1);
x86_fld_membase(inst, X86_ESP, 0, 0);
x86_alu_reg_imm(inst, X86_ADD, X86_ESP, sizeof(jit_float32));
}
[=freg, lreg] -> {
x86_push_reg(inst, %2);
x86_push_reg(inst, $2);
x86_fild_membase(inst, X86_ESP, 0, 1);
x86_fst_membase(inst, X86_ESP, 0, 0, 1);
x86_fld_membase(inst, X86_ESP, 0, 0);
x86_alu_reg_imm(inst, X86_ADD, X86_ESP, sizeof(jit_long));
}
JIT_OP_LONG_TO_FLOAT64:
[=freg, local] -> {
x86_alu_reg_imm(inst, X86_SUB, X86_ESP, sizeof(jit_float64));
x86_fild_membase(inst, X86_EBP, $2, 1);
x86_fst_membase(inst, X86_ESP, 0, 1, 1);
x86_fld_membase(inst, X86_ESP, 0, 1);
x86_alu_reg_imm(inst, X86_ADD, X86_ESP, sizeof(jit_float64));
}
[=freg, lreg] -> {
x86_push_reg(inst, %2);
x86_push_reg(inst, $2);
x86_fild_membase(inst, X86_ESP, 0, 1);
x86_fst_membase(inst, X86_ESP, 0, 1, 1);
x86_fld_membase(inst, X86_ESP, 0, 1);
x86_alu_reg_imm(inst, X86_ADD, X86_ESP, sizeof(jit_long));
}
@ -216,7 +277,7 @@ JIT_OP_LONG_TO_NFLOAT:
x86_alu_reg_imm(inst, X86_ADD, X86_ESP, sizeof(jit_long));
}
JIT_OP_ULONG_TO_NFLOAT: more_space
JIT_OP_ULONG_TO_FLOAT32, JIT_OP_ULONG_TO_FLOAT64, JIT_OP_ULONG_TO_NFLOAT: more_space
[=freg, lreg] -> {
/* TODO: review wrt relocation for elf pre-compilation */
static float f2pow64;
@ -230,15 +291,25 @@ JIT_OP_ULONG_TO_NFLOAT: more_space
x86_push_reg(inst, %2);
x86_push_reg(inst, $2);
x86_fild_membase(inst, X86_ESP, 0, 1);
x86_alu_reg_imm(inst, X86_ADD, X86_ESP, sizeof(jit_long));
x86_test_reg_reg(inst, %2, %2);
patch = inst;
x86_branch8(inst, X86_CC_NS, 0, 1);
x86_fp_op_mem(inst, X86_FADD, &f2pow64, 0);
x86_patch(patch, inst);
if(insn->opcode == JIT_OP_ULONG_TO_FLOAT32)
{
x86_fst_membase(inst, X86_ESP, 0, 0, 1);
x86_fld_membase(inst, X86_ESP, 0, 0);
}
else if(insn->opcode == JIT_OP_ULONG_TO_FLOAT64)
{
x86_fst_membase(inst, X86_ESP, 0, 1, 1);
x86_fld_membase(inst, X86_ESP, 0, 1);
}
x86_alu_reg_imm(inst, X86_ADD, X86_ESP, sizeof(jit_long));
}
JIT_OP_NFLOAT_TO_FLOAT32: stack
JIT_OP_FLOAT64_TO_FLOAT32, JIT_OP_NFLOAT_TO_FLOAT32: stack
[freg] -> {
x86_alu_reg_imm(inst, X86_SUB, X86_ESP, sizeof(void *));
x86_fst_membase(inst, X86_ESP, 0, 0, 1);
@ -254,7 +325,7 @@ JIT_OP_NFLOAT_TO_FLOAT64: stack
x86_alu_reg_imm(inst, X86_ADD, X86_ESP, sizeof(jit_float64));
}
JIT_OP_FLOAT32_TO_NFLOAT, JIT_OP_FLOAT64_TO_NFLOAT: copy, stack
JIT_OP_FLOAT32_TO_NFLOAT, JIT_OP_FLOAT32_TO_FLOAT64, JIT_OP_FLOAT64_TO_NFLOAT: copy, stack
[freg] -> {
/* Nothing to do: loading the value onto the FP stack is sufficient */
}

148
tests/math.pas

@ -90,6 +90,131 @@ begin
nfneg := -f;
end;
procedure run_conversion_tests;
var
f: ShortReal;
d: Real;
nf: LongReal;
i: Integer;
u: Cardinal;
l: LongInt;
ul: LongCard;
begin
{ Tests for conversions from ShortReal to other types }
f:= 1.5;
run("math_conv_float32_int 1.5", Integer(f) = 1);
f:= ShortReal(-1.5);
run("math_conv_float32_int -1.5", Integer(f) = -1);
f:= 1.5;
run("math_conv_float32_uint 1.5", Cardinal(f) = Cardinal(1));
{ The float mantissa is less than 32 bit so precision might get lost }
f:= ShortReal(81234500H);
run("math_conv_float32_uint 81234500H", Cardinal(f) = Cardinal(81234500H));
f:= 1.5;
run("math_conv_float32_long 1.5", LongInt(f) = LongInt(1));
f:= ShortReal(-1.5);
run("math_conv_float32_long -1.5", LongInt(f) = LongInt(-1));
f:= 1.5;
run("math_conv_float32_ulong 1.5", LongCard(f) = LongCard(1));
{ The 32-bit float fraction is less than 32 bit so precision might get lost }
f:= ShortReal(81234500H);
run("math_conv_float32_ulong 81234500H", LongCard(f) = LongCard(81234500H));
{ Tests for conversions from Real to other types }
d := 1.5;
run("math_conv_float64_int 1.5", Integer(d) = 1);
d := Real(-1.5);
run("math_conv_float64_int -1.5", Integer(d) = -1);
d := 1.5;
run("math_conv_float64_uint 1.5", Cardinal(d) = Cardinal(1));
d := Real(81234567H);
run("math_conv_float64_uint 81234567H", Cardinal(d) = Cardinal(81234567H));
d := 1.5;
run("math_conv_float64_long 1.5", LongInt(d) = LongInt(1));
d := Real(-1.5);
run("math_conv_float64_long -1.5", LongInt(d) = LongInt(-1));
d := 1.5;
run("math_conv_float64_ulong 1.5", LongCard(d) = LongCard(1));
{ The 64-bit float fraction is less than 64 bit so precision might get lost }
d := Real(8123456789ABC000H);
run("math_conv_float64_ulong 8123456789ABC000H", LongCard(d) = LongCard(8123456789ABC000H));
{ Tests for conversions from LongReal to other types }
nf := 1.5;
run("math_conv_nfloat_int 1.5", Integer(nf) = 1);
nf := LongReal(-1.5);
run("math_conv_nfloat_int -1.5", Integer(nf) = -1);
nf := 1.5;
run("math_conv_nfloat_uint 1.5", Cardinal(nf) = Cardinal(1));
nf := LongReal(81234567H);
run("math_conv_nfloat_uint 81234567H", Cardinal(nf) = Cardinal(81234567H));
nf := 1.5;
run("math_conv_nfloat_long 1.5", LongInt(nf) = LongInt(1));
nf := LongReal(-1.5);
run("math_conv_nfloat_long -1.5", LongInt(nf) = LongInt(-1));
nf := 1.5;
run("math_conv_nfloat_ulong 1.5", LongCard(nf) = LongCard(1));
{ The native float fraction might less than 64 bit so precision might get lost }
nf:= LongReal(8123456789ABC000H);
run("math_conv_nfloat_ulong 8123456789ABC000H", LongCard(nf) = LongCard(8123456789ABC000H));
{ Tests for conversions from integer types to ShortReal }
i := 1;
runf("math_conv_int_float32 1", ShortReal(i), ShortReal(1.0), 0.00001);
i := -1;
runf("math_conv_int_float32 -1", ShortReal(i), ShortReal(-1.0), 0.00001);
u := 1;
runf("math_conv_uint_float32 1", ShortReal(u), ShortReal(1.0), 0.00001);
u := 81234500H;
runf("math_conv_uint_float32 81234500H", ShortReal(u), ShortReal(81234500H), 0.00001);
l := 1;
runf("math_conv_long_float32 1", ShortReal(l), ShortReal(1.0), 0.00001);
l := -1;
runf("math_conv_long_float32 -1", ShortReal(l), ShortReal(-1.0), 0.00001);
ul := 1;
runf("math_conv_ulong_float32 1", ShortReal(ul), ShortReal(1.0), 0.00001);
ul := 8123450000000000H;
runf("math_conv_ulong_float32 8123450000000000H", ShortReal(ul), ShortReal(8123450000000000H), 0.00001);
{ Tests for conversions from integer types to Real }
i := 1;
rund("math_conv_int_float64 1", Real(i), Real(1.0), 0.00001);
i := -1;
rund("math_conv_int_float64 -1", Real(i), Real(-1.0), 0.00001);
u := 1;
rund("math_conv_uint_float64 1", Real(u), Real(1.0), 0.00001);
u := 81234567H;
rund("math_conv_uint_float64 81234567H", Real(u), Real(81234567H), 0.00001);
l := 1;
rund("math_conv_long_float64 1", Real(l), Real(1.0), 0.00001);
l := -1;
rund("math_conv_long_float64 -1", Real(l), Real(-1.0), 0.00001);
ul := 1;
rund("math_conv_ulong_float64 1", Real(ul), Real(1.0), 0.00001);
ul := 8123456789ABC000H;
rund("math_conv_ulong_float64 8123456789ABC000H", Real(ul), Real(8123456789ABC000H), 0.00001);
{ Tests for conversions from integer types to LomgReal }
i := 1;
runn("math_conv_int_nfloat 1", LongReal(i), LongReal(1.0), 0.00001);
i := -1;
runn("math_conv_int_nfloat -1", LongReal(i), LongReal(-1.0), 0.00001);
u := 1;
runn("math_conv_uint_nfloat 1", LongReal(u), LongReal(1.0), 0.00001);
u := 81234567H;
runn("math_conv_uint_nfloat 81234567H", LongReal(u), LongReal(81234567H), 0.00001);
l := 1;
runn("math_conv_long_nfloat 1", LongReal(l), LongReal(1.0), 0.00001);
l := -1;
runn("math_conv_long_nfloat -1", LongReal(l), LongReal(-1.0), 0.00001);
ul := 1;
runn("math_conv_ulong_nfloat 1", LongReal(ul), LongReal(1.0), 0.00001);
ul := 8123456789ABC000H;
runn("math_conv_ulong_nfloat 8123456789ABC000H", LongReal(ul), LongReal(8123456789ABC000H), 0.00001);
end;
procedure run_tests;
var
b: Byte;
@ -348,18 +473,19 @@ begin
runn("math_n_sqrt_2", Sqrt(LongReal(2.0)), LongReal(1.4142), 0.0001);
n := Sqrt(LongReal(-1.0));
run("math_n_sqrt_m1", IsNaN(n));
runn("math_n_ceil_1.5", Ceil(LongReal(1.5)), LongReal(2.0), 0.00001);
runn("math_n_ceil_m1.5", Ceil(LongReal(-1.5)), LongReal(-1.0), 0.00001);
runn("math_n_floor_1.5", Floor(LongReal(1.5)), LongReal(1.0), 0.00001);
runn("math_n_floor_m1.5", Floor(LongReal(-1.5)), LongReal(-2.0), 0.00001);
runn("math_n_rint_1.5", Rint(LongReal(1.5)), LongReal(2.0), 0.00001);
runn("math_n_rint_2.5", Rint(LongReal(2.5)), LongReal(2.0), 0.00001);
runn("math_n_round_1.5", Round(LongReal(1.5)), LongReal(2.0), 0.00001);
runn("math_n_round_2.5", Round(LongReal(2.5)), LongReal(3.0), 0.00001);
runn("math_n_trunc_1.5", Trunc(LongReal(1.5)), LongReal(1.0), 0.00001);
runn("math_n_trunc_2.5", Trunc(LongReal(2.5)), LongReal(2.0), 0.00001);
runn("math_n_trunc_m1.5", Trunc(LongReal(-1.5)), LongReal(-1.0), 0.00001);
runn("math_n_ceil 1.5", Ceil(LongReal(1.5)), LongReal(2.0), 0.00001);
runn("math_n_ceil -1.5", Ceil(LongReal(-1.5)), LongReal(-1.0), 0.00001);
runn("math_n_floor 1.5", Floor(LongReal(1.5)), LongReal(1.0), 0.00001);
runn("math_n_floor -1.5", Floor(LongReal(-1.5)), LongReal(-2.0), 0.00001);
runn("math_n_rint 1.5", Rint(LongReal(1.5)), LongReal(2.0), 0.00001);
runn("math_n_rint 2.5", Rint(LongReal(2.5)), LongReal(2.0), 0.00001);
runn("math_n_round 1.5", Round(LongReal(1.5)), LongReal(2.0), 0.00001);
runn("math_n_round 2.5", Round(LongReal(2.5)), LongReal(3.0), 0.00001);
runn("math_n_trunc 1.5", Trunc(LongReal(1.5)), LongReal(1.0), 0.00001);
runn("math_n_trunc 2.5", Trunc(LongReal(2.5)), LongReal(2.0), 0.00001);
runn("math_n_trunc -1.5", Trunc(LongReal(-1.5)), LongReal(-1.0), 0.00001);
run_conversion_tests;
end;
begin

Loading…
Cancel
Save