From: Taylor R Campbell Date: Thu, 12 Nov 2009 21:44:58 +0000 (-0500) Subject: Fix i386 and x86-64 generic multiplication hooks on fixnums. X-Git-Tag: 20100708-Gtk~246 X-Git-Url: https://birchwood-abbey.net/git?a=commitdiff_plain;h=84b1f57fbe67265816dde2cec64786e09ddcf349;p=mit-scheme.git Fix i386 and x86-64 generic multiplication hooks on fixnums. Before multiplying, both tags must be cleared, and one of the operands must be shifted to include a factor of 2^6. Shifting both operands, so that there is an extra factor of 2^12, or not clearing the tag on both operands, is wrong. However, this didn't affect any real code, since the fixnum case of generic multiplication is always open-coded by the compiler unless you futz with compiler switches. --- diff --git a/src/microcode/cmpauxmd/i386.m4 b/src/microcode/cmpauxmd/i386.m4 index 4b4f23e99..fda7aa750 100644 --- a/src/microcode/cmpauxmd/i386.m4 +++ b/src/microcode/cmpauxmd/i386.m4 @@ -862,6 +862,10 @@ asm_generic_$1_fail: jmp scheme_to_interface') define(define_binary_operation, +`define_binary_operation_with_setup($1,$2,$3,$4, + `OP(shl,l) TW(IMM(TC_LENGTH),REG(eax))')') + +define(define_binary_operation_with_setup, `declare_alignment(2) define_hook_label(generic_$1) OP(pop,l) REG(edx) @@ -886,7 +890,7 @@ asm_generic_$1_fail: asm_generic_$1_fix: OP(mov,l) TW(REG(edx),REG(eax)) OP(mov,l) TW(REG(ebx),REG(ecx)) - OP(shl,l) TW(IMM(TC_LENGTH),REG(eax)) + $5 # Set up eax. OP(shl,l) TW(IMM(TC_LENGTH),REG(ecx)) OP($3,l) TW(REG(ecx),REG(eax)) # subl jo asm_generic_$1_fail @@ -996,7 +1000,13 @@ define_unary_predicate(zero,2d,je,je) # define_binary_operation( $1, $2, $3, $4) define_binary_operation(add,2b,add,fadd) define_binary_operation(subtract,28,sub,fsub) -define_binary_operation(multiply,29,imul,fmul) + +# To set up eax, kill its tag, but leave it unshifted; the other +# operand will be shifted already, so that it will already include the +# factor of 2^6 desired in the product. +define_binary_operation_with_setup(multiply,29,imul,fmul, + `OP(and,l) TW(rmask,REG(eax))') + # Divide needs to check for 0, so we cant really use the following # define_binary_operation(divide,23,NONE,fdiv) diff --git a/src/microcode/cmpauxmd/x86-64.m4 b/src/microcode/cmpauxmd/x86-64.m4 index 52cf07995..7c4f8ac6c 100644 --- a/src/microcode/cmpauxmd/x86-64.m4 +++ b/src/microcode/cmpauxmd/x86-64.m4 @@ -657,10 +657,10 @@ asm_generic_$1_fail: jmp scheme_to_interface') define(define_binary_operation, -`define_binary_operation_with_fixup($1,$2,$3,$4, +`define_binary_operation_with_setup($1,$2,$3,$4, `OP(shl,q) TW(IMM(TC_LENGTH),REG(rax))')') -define(define_binary_operation_with_fixup, +define(define_binary_operation_with_setup, `declare_alignment(2) define_hook_label(generic_$1) OP(pop,q) REG(rdx) @@ -829,8 +829,11 @@ define_unary_predicate(zero,2d,je) define_binary_operation(add,2b,add,addsd) define_binary_operation(subtract,28,sub,subsd) -# No fixup -- leave it unshifted. -define_binary_operation_with_fixup(multiply,29,imul,mulsd) +# To set up rax, kill its tag, but leave it unshifted; the other +# operand will be shifted already, so that it will already include the +# factor of 2^6 desired in the product. +define_binary_operation_with_setup(multiply,29,imul,mulsd, + `OP(and,q) TW(rmask,REG(rax))') # define_binary_predicate(name,index,jcc) # define_binary_predicate( $1, $2, $3)