зеркало из https://github.com/mozilla/gecko-dev.git
add md stuff for freebsd.
This commit is contained in:
Родитель
cdd493b664
Коммит
d3275a4eb0
|
@ -36,6 +36,7 @@ LOCAL_MD_EXPORTS_x86 = x86ArgumentList.h \
|
|||
x86Float.h \
|
||||
x86Formatter.h \
|
||||
x86Linux_Support.h \
|
||||
x86FreeBSD_Support.h \
|
||||
x86Opcode.h \
|
||||
x86StdCall.h \
|
||||
x86Win32Cpu.h \
|
||||
|
@ -67,6 +68,11 @@ ASFILES = x86Linux.s
|
|||
OS_SUPPORT = x86Linux_Support.cpp
|
||||
endif
|
||||
|
||||
ifeq ($(OS_ARCH),FreeBSD)
|
||||
ASFILES = x86FreeBSD.s
|
||||
OS_SUPPORT = x86FreeBSD_Support.cpp
|
||||
endif
|
||||
|
||||
#######################################################################
|
||||
# (4) Execute "component" rules. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
@ -86,7 +92,7 @@ x86-win32.nad.burg.cpp: x86-win32.nad.burg $(BURG)
|
|||
|
||||
x86-win32.nad.burg: x86-win32.nad $(DEPTH)/Compiler/PrimitiveGraph/PrimitiveOperations $(DEPTH)/Tools/Nad/nad.pl
|
||||
$(PERL) $(DEPTH)/Tools/Nad/nad.pl $< $(DEPTH)/Compiler/PrimitiveGraph/PrimitiveOperations \
|
||||
$(LOCAL_EXPORT_DIR)/PrimitiveOperations.h \
|
||||
$(LOCAL_EXPORT_DIR)/PrimitiveOperations.h \
|
||||
$(DEPTH)/Compiler/PrimitiveGraph/PrimitiveOperations.cpp \
|
||||
$<.burg.h > $@
|
||||
else
|
||||
|
|
|
@ -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 "x86FreeBSD.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 %eax /* Save all volatiles */
|
||||
push %ebx
|
||||
push %ecx
|
||||
push %edx
|
||||
push 20(%esp) /* Push the second argument to compileAndBackPatchMethod (return address) */
|
||||
push 20(%esp) /* Push the first argument to compileAndBackPatchMethod (cacheEntry) */
|
||||
call compileAndBackPatchMethod
|
||||
pop %edx /* Remove passes arguments */
|
||||
pop %edx /* Remove passes arguments */
|
||||
mov %eax, 16(%esp) /* Overwrite cacheEntry with function address */
|
||||
pop %edx /* Restore volatiles */
|
||||
pop %ecx
|
||||
pop %ebx
|
||||
pop %eax
|
||||
ret /* Jump to function leaving the return address at the top of the stack */
|
||||
|
||||
GLOBAL_ENTRY_END(staticCompileStub)
|
||||
|
||||
GLOBAL_ENTRY_START(compileStub)
|
||||
push 0xefbeadde /* This is a dummy immediate that will be filled in by */
|
||||
jmp staticCompileStub /* generateCompileStub with the cacheEntry */
|
||||
GLOBAL_ENTRY_END(compileStub)
|
||||
|
||||
/*
|
||||
* 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)
|
|
@ -0,0 +1,125 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
x86FreeBSD_Support.cpp
|
||||
*/
|
||||
|
||||
#include "NativeCodeCache.h"
|
||||
#include <string.h>
|
||||
#include "Fundamentals.h"
|
||||
#include "MemoryAccess.h"
|
||||
#include "x86FreeBSD_Support.h"
|
||||
|
||||
|
||||
void* JNIenv = 0;
|
||||
|
||||
extern ClassWorld world;
|
||||
|
||||
#ifdef DEBUG
|
||||
// Pointer to the instruction after the call (used by exception handler to check
|
||||
// I wanted to use:
|
||||
// void* compileStubReEntryPoint = (void*) ((Uint8*)staticCompileStub + 17);
|
||||
// but MSDev appears to have a bug, in that compileStubReEntryPoint will be set == (void*)staticCompileStub
|
||||
// which is clearly wrong.
|
||||
void* compileStubAddress = (void*)staticCompileStub;
|
||||
void* compileStubReEntryPoint = (Uint8*)compileStubAddress + 17;
|
||||
#endif // DEBUG
|
||||
|
||||
void *
|
||||
generateNativeStub(NativeCodeCache& inCache, const CacheEntry& inCacheEntry, void *nativeFunction)
|
||||
{
|
||||
Method* method = inCacheEntry.descriptor.method;
|
||||
Uint32 nWords = method->getSignature().nArguments;
|
||||
|
||||
assert(method->getModifiers() & CR_METHOD_NATIVE);
|
||||
|
||||
extern Uint32 sysInvokeNativeStubs[];
|
||||
Uint8 stubSize = 10;
|
||||
void* stub;
|
||||
|
||||
// Write out the native stub
|
||||
stub = inCache.acquireMemory(stubSize);
|
||||
Uint8* where = (Uint8*)stub;
|
||||
*where++ = 0x68; // pushl
|
||||
writeLittleWordUnaligned(where, (uint32)(nativeFunction));
|
||||
where += 4;
|
||||
*where++ = 0xe9; // jmp
|
||||
writeLittleWordUnaligned(where, (Uint8 *) sysInvokeNativeStubs[nWords] - (where + 4));
|
||||
|
||||
// Return the address of the stub.
|
||||
return ((void*)stub);
|
||||
}
|
||||
|
||||
void *
|
||||
generateJNIGlue(NativeCodeCache& inCache,
|
||||
const CacheEntry& inCacheEntry,
|
||||
void *nativeFunction)
|
||||
{
|
||||
void* stub;
|
||||
Method* method = inCacheEntry.descriptor.method;
|
||||
assert(method->getModifiers() & CR_METHOD_NATIVE);
|
||||
|
||||
Uint8 stubSize = 12;
|
||||
|
||||
// Write out the JNI compile stub
|
||||
stub = inCache.acquireMemory(stubSize);
|
||||
Uint8* where = (Uint8*) stub;
|
||||
*where++ = 0x58; // popl %eax
|
||||
*where++ = 0x68; // pushl
|
||||
writeLittleWordUnaligned(where, (Uint32) JNIenv);
|
||||
where += 4;
|
||||
*where++ = 0xe9; // jmp
|
||||
writeLittleWordUnaligned(where, reinterpret_cast<Uint32>(nativeFunction) - Uint32(where + 4));
|
||||
return stub;
|
||||
}
|
||||
|
||||
void *
|
||||
generateCompileStub(NativeCodeCache& inCache, const CacheEntry& inCacheEntry)
|
||||
{
|
||||
void* stub;
|
||||
uint8 stubSize = 10;
|
||||
|
||||
// Write out the dynamic compile stub
|
||||
stub = inCache.acquireMemory(stubSize);
|
||||
Uint8* where = (Uint8*)stub;
|
||||
*where++ = 0x68; // pushl
|
||||
writeLittleWordUnaligned(where, (uint32)(&inCacheEntry));
|
||||
where += 4;
|
||||
*where++ = 0xe9; // jmp
|
||||
writeLittleWordUnaligned(where, (Uint8 *) staticCompileStub - (where + 4));
|
||||
|
||||
// Return the address of the dynamic stub.
|
||||
return ((void*)stub);
|
||||
}
|
||||
|
||||
void*
|
||||
backPatchMethod(void* inMethodAddress, void* inLastPC, void* /*inUserDefined*/)
|
||||
{
|
||||
|
||||
uint32 curAddress = (uint32) inLastPC;
|
||||
uint32 methodAddress = (uint32) inMethodAddress;
|
||||
|
||||
// Compute the relative branch
|
||||
uint32* relativeBranch = ((uint32*)inLastPC)-1;
|
||||
int32 offset = methodAddress - curAddress;
|
||||
|
||||
// Backpatch the method.
|
||||
writeLittleWordUnaligned((void*)relativeBranch, offset);
|
||||
|
||||
return (inMethodAddress);
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _X86_FREEBSD_SUPPORT_H_
|
||||
#define _X86_FREEBSD_SUPPORT_H_
|
||||
|
||||
#include "prtypes.h"
|
||||
|
||||
PR_BEGIN_EXTERN_C
|
||||
|
||||
extern void staticCompileStub();
|
||||
|
||||
PR_END_EXTERN_C
|
||||
|
||||
#endif // _X86_FREEBSD_SUPPORT_H_
|
||||
|
Загрузка…
Ссылка в новой задаче