A bunch of grunge work to reduce the amount of OS-dependent code in

ElectricalFire sources.  The end result eliminated nearly all of the
differences between FreeBSD and Linux in the source code.  It also
increased the amount of sharing between Win32 and unix code.

+   Renamed files and classes that were inappropriately named, i.e. the
    names started with 'x86Win32', but the code was for generic x86, not
    specific to Win32.

+   Eliminated several gratuitous duplicated files, e.g. x86Linux.s and
    x86FreeBSD.s were essentially identical.

+   Shared code that had been duplicated in x86Win32_Support.cpp,
    x86Linux_Support.cpp and x86FreeBSD_Support.cpp.  Created
    x86GenStub.cpp, which contains only XP code, to replace them all.
This commit is contained in:
fur%netscape.com 1999-02-28 00:18:23 +00:00
Родитель f08b61d790
Коммит 4eeb386cec
8 изменённых файлов: 598 добавлений и 40 удалений

Просмотреть файл

@ -28,6 +28,7 @@ CPPSRCS = x86.nad.burg.cpp \
x86Emitter.cpp \
x86Float.cpp \
x86Formatter.cpp \
x86GenStub.cpp \
x86Instruction.cpp \
x86StdCall.cpp \
$(OS_SUPPORT) \
@ -36,8 +37,6 @@ CPPSRCS = x86.nad.burg.cpp \
LOCAL_MD_EXPORTS_x86 = x86ArgumentList.h \
x86Float.h \
x86Formatter.h \
x86Linux_Support.h \
x86FreeBSD_Support.h \
x86Opcode.h \
x86StdCall.h \
x86Cpu.h \
@ -61,17 +60,9 @@ include $(DEPTH)/config/config.mk
# Generation of OS-specific support files
#
ifeq ($(OS_ARCH),WINNT)
OS_SUPPORT = x86Win32_Support.cpp
endif
ifeq ($(OS_ARCH),Linux)
ASFILES = x86Linux.s
OS_SUPPORT = x86Linux_Support.cpp
endif
ifeq ($(OS_ARCH),FreeBSD)
ASFILES = x86FreeBSD.s
OS_SUPPORT = x86FreeBSD_Support.cpp
OS_SUPPORT = x86Stub.cpp
else
ASFILES = x86Stub_gas.s
endif
#######################################################################

Просмотреть файл

@ -694,33 +694,7 @@ emit_Logic_L(Primitive& inPrimitive, x86DoubleOpDirCode insnType)
redefineTemporary(insnHi, vrHi, 0);
}
#if defined(WIN32)
# include "x86Arith64.h"
#elif defined(LINUX) || defined(FREEBSD)
extern "C" {
extern void x86Mul64Bit(void);
extern void x86Div64Bit(void);
extern void x86Mod64Bit(void);
extern void x86Shl64Bit(void);
extern void x86Shr64Bit(void);
extern void x86Sar64Bit(void);
extern void x86ThreeWayCMP_L(void);
extern void x86ThreeWayCMPC_L(void) {trespass("Not implemented");}
extern void x86Extract64Bit(void);
};
#endif
#if !defined(WIN32) && !defined(LINUX) && !defined(FREEBSD)
static void x86Mul64Bit() {trespass("Not implemented");}
static void x86Div64Bit() {trespass("Not implemented");}
static void x86Mod64Bit() {trespass("Not implemented");}
static void x86Shl64Bit() {trespass("Not implemented");}
static void x86Shr64Bit() {trespass("Not implemented");}
static void x86Sar64Bit() {trespass("Not implemented");}
static void x86ThreeWayCMP_L() {trespass("Not implemented");}
static void x86ThreeWayCMPC_L() {trespass("Not implemented");}
static void x86Extract64Bit() {trespass("Not implemented");}
#endif
#include "x86Arith64.h"
void x86Emitter::
emit_Mul_L(Primitive& inPrimitive)

Просмотреть файл

Просмотреть файл

Просмотреть файл

Просмотреть файл

Просмотреть файл

Просмотреть файл

@ -0,0 +1,593 @@
/* -*- Mode: asm; tab-width:4; truncate-lines:t -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
.file "x86Linux.S"
#define ALIGN .align 16
#define SYMBOL_NAME(name) name
#define SYMBOL_NAME_LABEL(name) name##:
#define GLOBAL_ENTRY_START(name) \
ALIGN; \
.globl SYMBOL_NAME(name); \
.type SYMBOL_NAME(name),@function; \
SYMBOL_NAME_LABEL(name)
#define GLOBAL_ENTRY_END(name) \
SYMBOL_NAME_LABEL(.L##name); \
.size SYMBOL_NAME(name),SYMBOL_NAME(.L##name)-SYMBOL_NAME(name)
GLOBAL_ENTRY_START(staticCompileStub)
push %ebp /* Make stack frame */
mov %esp,%ebp
/* Even though ESI and EDI are non-volatile (callee-saved) registers, we need to
preserve them here in case an exception is thrown. The exception-handling
code expects to encounter this specially-prepared stack "guard" frame when
unwinding the stack. See x86ExceptionHandler.cpp. */
push %edi
push %esi
push %ebx /* XXX - Why push EBX ? It's caller-saved */
/* Call compileAndBackPatchMethod() with 2 args */
push 16(%esp) /* Push the second argument to compileAndBackPatchMethod (return address) */
push %eax /* Push the first argument to compileAndBackPatchMethod (cacheEntry) */
call compileAndBackPatchMethod
mov %ebp,%esp /* Pop stack frame */
pop %ebp
jmp *%eax /* Jump to function leaving the return address at the top of the stack */
GLOBAL_ENTRY_END(staticCompileStub)
/*
* 64bit Arithmetic Support Functions
*
* x86Extract64Bit
*
* Origin: Simon
* Purpose: signed right-aligned field extraction
* In: 64 bit source (on stack)
* 32 bit extraction size (on stack)
* Out: 64 bit result
* Note: Only works in range 1 <= b <= 63, b is extraction amount
*/
GLOBAL_ENTRY_START(x86Extract64Bit)
mov 4(%esp),%eax /* load low byte of a */
mov 12(%esp),%ecx /*load shift amount */
cmp $0x20,%ecx
jg greater32
/* extract <= than 32 bits
* shift amount = 32 - extract
*/
neg %ecx
add $0x20,%ecx /* ecx = 32 - extract */
shl %cl,%eax
sar %cl,%eax
cdq /* sign extend into EDX:EAX */
ret $12
greater32:
/* ext > 32 bits
* shift amount = 64 - extract
*/
mov 8(%esp),%edx /* load high byte of a */
neg %ecx
add $0x40,%ecx /* ecx = 64 - extract */
shl %cl,%edx
sar %cl,%edx
ret $12
GLOBAL_ENTRY_END(x86Extract64Bit)
/*
* 3WayCompare
*
* Origin: Symantec JIT
* Purpose: compare two longs
* In: two longs on the stack
* Out: depends on condition flags:
* less = -1
* equal = 0
* greater = 1
*/
GLOBAL_ENTRY_START(x86ThreeWayCMP_L)
/* edx:eax is tos, ecx:ebx is nos */
mov 8(%esp),%ecx
mov 16(%esp),%edx
cmp %edx,%ecx
jl lcmp_m1
jg lcmp_1
mov 4(%esp),%ecx
mov 12(%esp),%edx
cmp %edx,%ecx
ja lcmp_1
mov $0,%eax
jb lcmp_m1
ret $16
.align 4
lcmp_m1:
mov $-1,%eax
ret $16
.align 4
lcmp_1:
mov $1,%eax
ret $16
GLOBAL_ENTRY_END(x86ThreeWayCMP_L)
/*
* llmul
*
* Origin: Intel Code (via MSDev)
* Purpose: long multiply (same for signed/unsigned)
* In: args are passed on the stack:
* 1st pushed: multiplier (QWORD)
* 2nd pushed: multiplicand (QWORD)
* Out: EDX:EAX - product of multiplier and multiplicand
* Note: parameters are removed from the stack
* Uses: ECX
*/
GLOBAL_ENTRY_START(x86Mul64Bit)
/* A*B = (A.lo * B.lo) + (A.lo * B.hi) + (B.lo * A.hi) ??? */
mov 8(%esp),%eax /* A.hi */
mov 16(%esp),%ecx /* B.hi */
or %eax,%ecx /* test for both hiwords zero */
mov 12(%esp),%ecx /* B.lo */
jnz hard
/* easy case
* both are zero, just mult ALO and BLO
*/
mov 4(%esp),%eax /* A.lo */
mul %ecx /* A.lo * B.lo */
ret $16 /* callee restores the stack */
/* hard case */
hard:
push %ebx
mul %ecx /* A.hi * B.lo */
mov %eax,%ebx /* save result */
mov 8(%esp),%eax /* A.lo */
mull 14(%esp) /* A.lo * B.hi */
add %eax,%ebx /* ebx = ((A.lo * B.hi) + (A.hi * B.lo)) */
mov 8(%esp),%eax /* A.lo */
mul %ecx /* edx:eax = A.lo * B.lo */
add %ebx,%edx /* now edx has all the LO*HI stuff */
pop %ebx
ret $16 /* callee restores the stack */
GLOBAL_ENTRY_END(x86Mul64Bit)
/*
* lldiv
*
* Origin: Intel Code (via MSDev)
* Purpose: signed long divide
* In: args are passed on the stack:
* 1st pushed: divisor (QWORD)
* 2nd pushed: dividend (QWORD)
* Out: EDX:EAX contains the quotient (dividend/divisor)
* Note: parameters are removed from the stack
* Uses: ECX
*/
GLOBAL_ENTRY_START(x86Div64Bit)
push %edi
push %esi
push %ebx
/* Determine sign of the result (%edi = 0 if result is positive, non-zero
* otherwise) and make operands positive.
*/
xor %edi,%edi /* result sign assumed positive */
mov 20(%esp),%eax /* hi word of a */
or %eax,%eax /* test to see if signed */
jge L1 /* skip rest if a is already positive */
inc %edi /* complement result sign flag */
mov 16(%esp),%edx /* lo word of a */
neg %eax /* make a positive */
neg %edx
sbb $0,%eax
mov %eax,20(%esp) /* save positive value */
mov %edx,16(%esp)
L1:
mov 28(%esp),%eax /* hi word of b */
or %eax,%eax /* test to see if signed */
jge L2 /* skip rest if b is already positive */
inc %edi /* complement the result sign flag */
mov 24(%esp),%edx /* lo word of a */
neg %eax /* make b positive */
neg %edx
sbb $0,%eax
mov %eax,28(%esp) /* save positive value */
mov %edx,24(%esp)
L2:
/* Now do the divide. First look to see if the divisor is less than 4194304K.
* If so, then we can use a simple algorithm with word divides, otherwise
* things get a little more complex.
* NOTE - %eax currently contains the high order word of DVSR
*/
or %eax,%eax /* check to see if divisor < 4194304K */
jnz L3 /* nope, gotta do this the hard way */
mov 24(%esp),%ecx /* load divisor */
mov 20(%esp),%eax /* load high word of dividend */
xor %edx,%edx
div %ecx /* %eax <- high order bits of quotient */
mov %eax,%ebx /* save high bits of quotient */
mov 16(%esp),%eax /* %edx:%eax <- remainder:lo word of dividend */
div %ecx /* %eax <- low order bits of quotient */
mov %ebx,%edx /* %edx:%eax <- quotient */
jmp L4 /* set sign, restore stack and return */
/* Here we do it the hard way. Remember, %eax contains the high word of DVSR */
L3:
mov %eax,%ebx /* %ebx:ecx <- divisor */
mov 24(%esp),%ecx
mov 20(%esp),%edx /* %edx:%eax <- dividend */
mov 16(%esp),%eax
L5:
shr $1,%ebx /* shift divisor right one bit */
rcr $1,%ecx
shr $1,%edx /* shift dividend right one bit */
rcr $1,%eax
or %ebx,%ebx
jnz L5 /* loop until divisor < 4194304K */
div %ecx /* now divide, ignore remainder */
mov %eax,%esi /* save quotient */
/* We may be off by one, so to check, we will multiply the quotient
* by the divisor and check the result against the orignal dividend
* Note that we must also check for overflow, which can occur if the
* dividend is close to 2**64 and the quotient is off by 1.
*/
mull 28(%esp) /* QUOT * HIWORD(DVSR) */
mov %eax,%ecx
mov 24(%esp),%eax
mul %esi /* QUOT * LOWORD(DVSR) */
add %ecx,%edx /* %EDX:%EAX = QUOT * DVSR */
jc L6 /* carry means Quotient is off by 1 */
/* do long compare here between original dividend and the result of the
* multiply in %edx:%eax. If original is larger or equal, we are ok, otherwise
* subtract one (1) from the quotient.
*/
cmp 20(%esp),%edx /* compare hi words of result and original */
ja L6 /* if result > original, do subtract */
jb L7 /* if result < original, we are ok */
cmp 16(%esp),%eax /* hi words are equal, compare lo words */
jbe L7 /* if less or equal we are ok, else subtract */
L6:
dec %esi /* subtract 1 from quotient */
L7:
xor %edx,%edx /* %edx:%eax <- quotient */
mov %esi,%eax
/* Just the cleanup left to do. %edx:%eax contains the quotient. Set the sign
* according to the save value, cleanup the stack, and return.
*/
L4:
dec %edi /* check to see if result is negative */
jnz L8 /* if %EDI == 0, result should be negative */
neg %edx /* otherwise, negate the result */
neg %eax
sbb $0,%edx
/* Restore the saved registers and return. */
L8:
pop %ebx
pop %esi
pop %edi
ret $16
GLOBAL_ENTRY_END(x86Div64Bit)
/*
* llrem
*
* Origin: MSDev
* Purpose: signed long remainder
* In: args are passed on the stack:
* 1st pushed: divisor (QWORD)
* 2nd pushed: dividend (QWORD)
* Out: %EDX:%EAX contains the quotient (dividend/divisor)
* Note: parameters are removed from the stack
* Uses: %ECX
*/
GLOBAL_ENTRY_START(x86Mod64Bit)
push %ebx
push %edi
/* Determine sign of the result (%edi = 0 if result is positive, non-zero
* otherwise) and make operands positive.
*/
xor %edi,%edi /* result sign assumed positive */
mov 16(%esp),%eax /* hi word of a */
or %eax,%eax /* test to see if signed */
jge LL1 /* skip rest if a is already positive */
inc %edi /* complement result sign flag bit */
mov 12(%esp),%edx /* lo word of a */
neg %eax /* make a positive */
neg %edx
sbb $0,%eax
mov %eax,16(%esp) /* save positive value */
mov %edx,12(%esp)
LL1:
mov 24(%esp),%eax /* hi word of b */
or %eax,%eax /* test to see if signed */
jge LL2 /* skip rest if b is already positive */
mov 20(%esp),%edx /* lo word of b */
neg %eax /* make b positive */
neg %edx
sbb $0,%eax
mov %eax,24(%esp) /* save positive value */
mov %edx,20(%esp)
LL2:
/* Now do the divide. First look to see if the divisor is less than 4194304K.
* If so, then we can use a simple algorithm with word divides, otherwise
* things get a little more complex.
* NOTE - %eax currently contains the high order word of DVSR
*/
or %eax,%eax /* check to see if divisor < 4194304K */
jnz LL3 /* nope, gotta do this the hard way */
mov 20(%esp),%ecx /* load divisor */
mov 16(%esp),%eax /* load high word of dividend */
xor %edx,%edx
div %ecx /* %edx <- remainder */
mov 12(%esp),%eax /* %edx:%eax <- remainder:lo word of dividend */
div %ecx /* %edx <- final remainder */
mov %edx,%eax /* %edx:%eax <- remainder */
xor %edx,%edx
dec %edi /* check result sign flag */
jns LL4 /* negate result, restore stack and return */
jmp LL8 /* result sign ok, restore stack and return */
/* Here we do it the hard way. Remember, %eax contains the high word of DVSR */
LL3:
mov %eax,%ebx /* %ebx:%ecx <- divisor */
mov 20(%esp),%ecx
mov 16(%esp),%edx /* %edx:%eax <- dividend */
mov 12(%esp),%eax
LL5:
shr $1,%ebx /* shift divisor right one bit */
rcr $1,%ecx
shr $1,%edx /* shift dividend right one bit */
rcr $1,%eax
or %ebx,%ebx
jnz LL5 /* loop until divisor < 4194304K */
div %ecx /* now divide, ignore remainder */
/* We may be off by one, so to check, we will multiply the quotient
* by the divisor and check the result against the orignal dividend
* Note that we must also check for overflow, which can occur if the
* dividend is close to 2**64 and the quotient is off by 1.
*/
mov %eax,%ecx /* save a copy of quotient in %ECX */
mull 24(%esp)
xchg %eax,%ecx /* save product, get quotient in %EAX */
mull 20(%esp)
add %ecx,%edx /* %EDX:%EAX = QUOT * DVSR */
jc LL6 /* carry means Quotient is off by 1 */
/* do long compare here between original dividend and the result of the
* multiply in %edx:%eax. If original is larger or equal, we are ok, otherwise
* subtract the original divisor from the result.
*/
cmp 16(%esp),%edx /* compare hi words of result and original */
ja LL6 /* if result > original, do subtract */
jb LL7 /* if result < original, we are ok */
cmp 12(%esp),%eax /* hi words are equal, compare lo words */
jbe LL7 /* if less or equal we are ok, else subtract */
LL6:
sub 20(%esp),%eax /* subtract divisor from result */
sbb 24(%esp),%edx
LL7:
/* Calculate remainder by subtracting the result from the original dividend.
* Since the result is already in a register, we will do the subtract in the
* opposite direction and negate the result if necessary.
*/
sub 12(%esp),%eax /* subtract dividend from result */
sbb 16(%esp),%edx
/* Now check the result sign flag to see if the result is supposed to be positive
* or negative. It is currently negated (because we subtracted in the 'wrong'
* direction), so if the sign flag is set we are done, otherwise we must negate
* the result to make it positive again.
*/
dec %edi /* check result sign flag */
jns LL8 /* result is ok, restore stack and return */
LL4:
neg %edx /* otherwise, negate the result */
neg %eax
sbb $0,%edx
/* Just the cleanup left to do. %edx:%eax contains the quotient.
* Restore the saved registers and return.
*/
LL8:
pop %edi
pop %ebx
ret $16
GLOBAL_ENTRY_END(x86Mod64Bit)
/*
* llshl
*
* Origin: MSDev. modified
* Purpose: long shift left
* In: args are passed on the stack: (FIX make fastcall)
* 1st pushed: amount (int)
* 2nd pushed: source (long)
* Out: %EDX:%EAX contains the result
* Note: parameters are removed from the stack
* Uses: %ECX, destroyed
*/
GLOBAL_ENTRY_START(x86Shl64Bit)
/* prepare from stack */
mov 4(%esp),%eax
mov 8(%esp),%edx
mov 12(%esp),%ecx
cmp $64,%cl
jae RETZERO
/* Handle shifts of between 0 and 31 bits */
cmp $32,%cl
jae MORE32
shld %eax,%edx
shl %cl,%eax
ret $12
/* Handle shifts of between 32 and 63 bits */
MORE32:
mov %eax,%edx
xor %eax,%eax
and $31,%cl
shl %cl,%edx
ret $12
/* return 0 in %edx:%eax */
RETZERO:
xor %eax,%eax
xor %edx,%edx
ret $12
GLOBAL_ENTRY_END(x86Shl64Bit)
/*
* llshr
*
* Origin: MSDev. modified
* Purpose: long shift right
* In: args are passed on the stack: (FIX make fastcall)
* 1st pushed: amount (int)
* 2nd pushed: source (long)
* Out: %EDX:%EAX contains the result
* Note: parameters are removed from the stack
* Uses: %ECX, destroyed
*/
GLOBAL_ENTRY_START(x86Shr64Bit)
/* prepare from stack */
mov 4(%esp),%eax
mov 8(%esp),%edx
mov 12(%esp),%ecx
cmp $64,%cl
jae RRETZERO
/* Handle shifts of between 0 and 31 bits */
cmp $32,%cl
jae MMORE32
shrd %edx,%eax
shr %cl,%edx
ret $12
/* Handle shifts of between 32 and 63 bits */
MMORE32:
mov %edx,%eax
xor %edx,%edx
and $31,%cl
shr %cl,%eax
ret $12
/* return 0 in %edx:%eax */
RRETZERO:
xor %eax,%eax
xor %edx,%edx
ret $12
GLOBAL_ENTRY_END(x86Shr64Bit)
/*
* llsar
*
* Origin: MSDev. modified
* Purpose: long shift right signed
* In: args are passed on the stack: (FIX make fastcall)
* 1st pushed: amount (int)
* 2nd pushed: source (long)
* Out: %EDX:%EAX contains the result
* Note: parameters are removed from the stack
* Uses: %ECX, destroyed
*/
GLOBAL_ENTRY_START(x86Sar64Bit)
/* prepare from stack */
mov 4(%esp),%eax
mov 8(%esp),%edx
mov 12(%esp),%ecx
/* Handle shifts of 64 bits or more (if shifting 64 bits or more, the result */
/* depends only on the high order bit of %edx). */
cmp $64,%cl
jae RETSIGN
/* Handle shifts of between 0 and 31 bits */
cmp $32,%cl
jae MMMORE32
shrd %edx,%eax
sar %cl,%edx
ret $12
/* Handle shifts of between 32 and 63 bits */
MMMORE32:
mov %edx,%eax
sar $31,%edx
and $31,%cl
sar %cl,%eax
ret $12
/* Return double precision 0 or -1, depending on the sign of %edx */
RETSIGN:
sar $31,%edx
mov %edx,%eax
ret $12
GLOBAL_ENTRY_END(x86Sar64Bit)