lkml.org 
[lkml]   [1999]   [Oct]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Date
Subjectpatch_v2: (on Alpha) emulating missing instructions
Here is a better patch for the emulation code of some missing alpha
instructions.

This time the code should be secure ;)
Also I've added a description to Documentation/Configure.help

- Luke & Dan

On Fri, 15 Oct 1999, Luke Deller wrote:

> Daniel & I tried to run Loki's new beta version of Civilization Call to
> Power for alpha linux on a multia (ev4 alpha). We got an illegal
> instruction exception. We discovered that it was compiled for ev6, and so
> contained instructions not supported by our CPU.
>
> So we have patched the linux kernel to emulate the instructions we needed.
> These instructions are:
> - byte/word load/store instructions (ldbu,stb,ldwu,stw)
> - some multimedia instructions (minsw, maxsw, minuw, maxuw, minsb, maxsb,
> minub, maxub)
>
> We have tried to make the emulation fairly fast - we have added it as some
> assembly language code to the "illegal instruction exception" kernel entry
> point in arch/alpha/kernel/entry.S:entIF. (Of course it's still faster
> to avoid emulation and use a binary compiled for your generation of alpha
> cpu).
>
> We put an option for enabling it in the "Kernel Hacking" section of the
> configuration.
>
> The patch is applied to kernel version 2.2.11
> (Loki say not to use 2.2.12 for Civilization CTP)
>
> We only wrote enough emulation code to get CivilizationCTP to run .. in the
> future it would be cool to see emulation of a more complete set of
> instructions in the kernel.
>
> Hope this is useful to somebody,
>
> Luke Deller & Daniel Potts.
>
> --------------------------------------------------------------------------
> Luke Deller luked@cse.unsw.edu.au
> _--_|\ Computer Engineering student
> / \ School of Computer Science and Engineering ? ? ? ?
> \_.--._* The University of New South Wales ~~^^~
> v Sydney, NSW 2052 AUSTRALIA o o
> -------------------------------------------------------ooO--(_)--Ooo------
>

--------------------------------------------------------------------------
Luke Deller luked@cse.unsw.edu.au
_--_|\ Computer Engineering student
/ \ School of Computer Science and Engineering ? ? ? ?
\_.--._* The University of New South Wales ~~^^~
v Sydney, NSW 2052 AUSTRALIA o o
-------------------------------------------------------ooO--(_)--Ooo------
diff -u --recursive --new-file v2.2.11/linux/Documentation/Configure.help linux/Documentation/Configure.help
--- v2.2.11/linux/Documentation/Configure.help Tue Aug 10 05:04:57 1999
+++ linux/Documentation/Configure.help Sat Oct 16 18:50:42 1999
@@ -11588,8 +11588,22 @@
Everyone using these boards should say Y here.
See "linux/Documentation/cpqarray.txt" for the current list of
boards supported by this driver, and for further information
- on the use of this driver.
-
+ on the use of this driver.
+
+Emulation of some extended alpha instructions
+CONFIG_ALPHA_EXTINSNS
+ This emulates some instructions which are not implemented in hardware
+ on some alpha CPU's. Emulation is provided for byte/word load/store
+ instructions (in the BWX instruction set extension) and some multimedia
+ extension instructions. If you say Y here then this emulation code will
+ be included in your kernel. Any of these instructions which your
+ hardware supports will not be emulated even if you have included the
+ emulation code in your kernel.
+
+ Here is the list of emulated instructions:
+ maxuw, maxsw, minuw, minsw, maxub, maxsb, minsb, minub,
+ stb, stw, ldbu, ldwu.
+
#
# A couple of things I keep forgetting:
# capitalize: AppleTalk, Ethernet, DOS, DMA, FAT, FTP, Internet,
diff -u --recursive --new-file v2.2.11/linux/arch/alpha/config.in linux/arch/alpha/config.in
--- v2.2.11/linux/arch/alpha/config.in Sun May 23 06:41:37 1999
+++ linux/arch/alpha/config.in Fri Oct 15 18:44:37 1999
@@ -280,6 +280,7 @@
#bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
tristate 'Kernel FP software completion' CONFIG_MATHEMU
+ bool 'Emulation of some extended instruction sets' CONFIG_ALPHA_EXTINSNS
else
define_bool CONFIG_MATHEMU y
fi
diff -u --recursive --new-file v2.2.11/linux/arch/alpha/defconfig linux/arch/alpha/defconfig
--- v2.2.11/linux/arch/alpha/defconfig Sun Jun 13 04:52:51 1999
+++ linux/arch/alpha/defconfig Fri Oct 15 18:44:37 1999
@@ -330,4 +330,5 @@
# Kernel hacking
#
CONFIG_MATHEMU=y
+# CONFIG_ALPHA_EXTINSNS is not set
# CONFIG_MAGIC_SYSRQ is not set
diff -u --recursive --new-file v2.2.11/linux/arch/alpha/kernel/entry.S linux/arch/alpha/kernel/entry.S
--- v2.2.11/linux/arch/alpha/kernel/entry.S Tue Aug 10 05:04:57 1999
+++ linux/arch/alpha/kernel/entry.S Sat Oct 16 19:04:41 1999
@@ -39,6 +39,13 @@
#define PF_PTRACED 0x00000010

/*
+ * This is used to tell if a memory address is in user land.
+ * This must be consistent with USER_DS in include/asm-alpha/uaccess.h
+ * and TASK_SIZE in include/asm-alpha/processor.h
+ */
+#define LOG2_TASKSIZE 42
+
+/*
* This defines the normal kernel pt-regs layout.
*
* regs 9-15 preserved by C code
@@ -173,10 +180,836 @@
jsr $31,do_entArith
.end entArith

+#ifdef CONFIG_ALPHA_EXTINSNS
+/* emulation of some extended alpha instructions */
+
+/* This emulation code doesn't handle segfaults as nicely as it should ..
+ * it just faults in kernel mode (resulting in the user task being killed)
+ * rather than pretending that the fault happened in userland (which should
+ * result in a SIGSEGV being sent to the user task).
+ *
+ * The emulation code ensures that the user doesn't access kernel space by
+ * checking that the high bits of the load/store virtual address are zero.
+ */
+
+.align 3
+.ent get_user_sp
+get_user_sp:
+ subq $30,6*8,$30
+ stq $0,0($30)
+ stq $1,8($30)
+ stq $16,16($30)
+ mov $25,$3
+ stq $22,24($30)
+ stq $23,32($30)
+ stq $24,40($30)
+ call_pal PAL_rdusp
+ ldq $24,40($30)
+ mov $3,$25
+ ldq $23,32($30)
+ ldq $22,24($30)
+ mov $0,$3
+ ldq $16,16($30)
+ ldq $1,8($30)
+ ldq $0,0($30)
+ addq $30,6*8,$30
+ ret $31,($5)
+.end get_user_sp
+
+.align 3
+.ent put_user_sp
+put_user_sp:
+ subq $30,5*8,$30
+ stq $16,0($30)
+ stq $22,8($30)
+ stq $23,16($30)
+ mov $3,$16
+ stq $24,24($30)
+ mov $1,$3
+ stq $25,32($30)
+ call_pal PAL_wrusp
+ ldq $25,32($30)
+ ldq $24,24($30)
+ mov $3,$1
+ ldq $23,16($30)
+ ldq $22,8($30)
+ ldq $16,0($30)
+ addq $30,5*8,$30
+ ret $31,($5)
+.end put_user_sp
+
+/* a code table .. make sure each entry is exactly 2 instructions */
+.align 3
+.ent get_ureg_table
+get_ureg0:
+ ldq $3,8*0($30)
+ ret $31,($5)
+get_ureg1:
+ ldq $3,8*1($30)
+ ret $31,($5)
+get_ureg2:
+ ldq $3,8*2($30)
+ ret $31,($5)
+get_ureg3:
+ ldq $3,8*3($30)
+ ret $31,($5)
+get_ureg4:
+ ldq $3,8*4($30)
+ ret $31,($5)
+get_ureg5:
+ ldq $3,8*5($30)
+ ret $31,($5)
+get_ureg6:
+ mov $6,$3
+ ret $31,($5)
+get_ureg7:
+ mov $7,$3
+ ret $31,($5)
+get_ureg8:
+ mov $8,$3
+ ret $31,($5)
+get_ureg9:
+ mov $9,$3
+ ret $31,($5)
+get_ureg10:
+ mov $10,$3
+ ret $31,($5)
+get_ureg11:
+ mov $11,$3
+ ret $31,($5)
+get_ureg12:
+ mov $12,$3
+ ret $31,($5)
+get_ureg13:
+ mov $13,$3
+ ret $31,($5)
+get_ureg14:
+ mov $14,$3
+ ret $31,($5)
+get_ureg15:
+ mov $15,$3
+ ret $31,($5)
+get_ureg16:
+ ldq $3,8*10($30)
+ ret $31,($5)
+get_ureg17:
+ ldq $3,8*11($30)
+ ret $31,($5)
+get_ureg18:
+ ldq $3,8*12($30)
+ ret $31,($5)
+get_ureg19:
+ mov $19,$3
+ ret $31,($5)
+get_ureg20:
+ mov $20,$3
+ ret $31,($5)
+get_ureg21:
+ mov $21,$3
+ ret $31,($5)
+get_ureg22:
+ mov $22,$3
+ ret $31,($5)
+get_ureg23:
+ mov $23,$3
+ ret $31,($5)
+get_ureg24:
+ mov $24,$3
+ ret $31,($5)
+get_ureg25:
+ mov $25,$3
+ ret $31,($5)
+get_ureg26:
+ mov $26,$3
+ ret $31,($5)
+get_ureg27:
+ mov $27,$3
+ ret $31,($5)
+get_ureg28:
+ mov $28,$3
+ ret $31,($5)
+get_ureg29:
+ ldq $3,9*8($30)
+ ret $31,($5)
+get_ureg30:
+ br $31,get_user_sp
+ ret $31,($5)
+get_ureg31:
+ mov $31,$3
+ ret $31,($5)
+.end get_ureg_table
+
+/* another code table .. make sure each entry is exactly 2 instructions */
+.align 3
+.ent put_ureg_table
+put_ureg0:
+ stq $3,8*0($30)
+ ret $31,($5)
+put_ureg1:
+ stq $3,8*1($30)
+ ret $31,($5)
+put_ureg2:
+ stq $3,8*2($30)
+ ret $31,($5)
+put_ureg3:
+ stq $3,8*3($30)
+ ret $31,($5)
+put_ureg4:
+ stq $3,8*4($30)
+ ret $31,($5)
+put_ureg5:
+ stq $3,8*5($30)
+ ret $31,($5)
+put_ureg6:
+ mov $3,$6
+ ret $31,($5)
+put_ureg7:
+ mov $3,$7
+ ret $31,($5)
+put_ureg8:
+ mov $3,$8
+ ret $31,($5)
+put_ureg9:
+ mov $3,$9
+ ret $31,($5)
+put_ureg10:
+ mov $3,$10
+ ret $31,($5)
+put_ureg11:
+ mov $3,$11
+ ret $31,($5)
+put_ureg12:
+ mov $3,$12
+ ret $31,($5)
+put_ureg13:
+ mov $3,$13
+ ret $31,($5)
+put_ureg14:
+ mov $3,$14
+ ret $31,($5)
+put_ureg15:
+ mov $3,$15
+ ret $31,($5)
+put_ureg16:
+ stq $3,8*10($30)
+ ret $31,($5)
+put_ureg17:
+ stq $3,8*11($30)
+ ret $31,($5)
+put_ureg18:
+ stq $3,8*12($30)
+ ret $31,($5)
+put_ureg19:
+ mov $3,$19
+ ret $31,($5)
+put_ureg20:
+ mov $3,$20
+ ret $31,($5)
+put_ureg21:
+ mov $3,$21
+ ret $31,($5)
+put_ureg22:
+ mov $3,$22
+ ret $31,($5)
+put_ureg23:
+ mov $3,$23
+ ret $31,($5)
+put_ureg24:
+ mov $3,$24
+ ret $31,($5)
+put_ureg25:
+ mov $3,$25
+ ret $31,($5)
+put_ureg26:
+ mov $3,$26
+ ret $31,($5)
+put_ureg27:
+ mov $3,$27
+ ret $31,($5)
+put_ureg28:
+ mov $3,$28
+ ret $31,($5)
+put_ureg29:
+ stq $3,9*8($30)
+ ret $31,($5)
+put_ureg30:
+ br $31,put_user_sp
+ ret $31,($5)
+put_ureg31:
+ ret $31,($5)
+.end put_ureg_table
+
+/* this macro trashes $5 & index, and returns user reg val in $3 */
+#define get_user_reg(index) \
+ br $3,1f ;\
+1: ;\
+ s8addq index,$3,index ;\
+ lda $5,get_ureg0-1b($31) ;\
+ addq index,$5,index ;\
+ jsr $5,(index),get_ureg16
+
+/* this macro trashes $3, $5 & index, and takes new user reg val in $3 */
+#define put_user_reg(index) \
+ br $5,1f ;\
+1: ;\
+ s8addq index,$5,index ;\
+ lda $5,put_ureg0-1b($31) ;\
+ addq index,$5,index ;\
+ jsr $5,(index),put_ureg16
+
+.align 3
+.globl emul_ldwu
+.ent emul_ldwu
+emul_ldwu:
+ stq $3,24($30)
+ stq $4,32($30)
+ stq $5,40($30)
+
+ srl $0,21,$1
+ srl $0,16,$2
+ and $1,0x1f,$1
+ sll $0,48,$0
+ and $2,0x1f,$2
+ sra $0,48,$0 /* $0 = disp */
+ get_user_reg($2) /* $3 = Rb */
+ addq $0,$3,$0
+ srl $0,LOG2_TASKSIZE,$5 /* if addr is not in userland, */
+ cmovne $5,$31,$0 /* then force a segfault by putting addr=0 */
+ ldq_u $3,0($0)
+ ldq_u $5,1($0)
+ extwl $3,$0,$3
+ extwh $5,$0,$5
+ or $3,$5,$3
+ put_user_reg($1)
+
+ ldq $5,40($30)
+ ldq $4,32($30)
+ ldq $3,24($30)
+ ldq $2,16($30)
+ ldq $1,8($30)
+ ldq $0,0($30)
+ addq $30,7*8,$30
+ call_pal PAL_rti
+.end emul_ldwu
+
+.align 3
+.globl emul_stw
+.ent emul_stw
+emul_stw:
+ stq $3,24($30)
+ stq $4,32($30)
+ stq $5,40($30)
+
+ srl $0,21,$1
+ srl $0,16,$2
+ and $1,0x1f,$1
+ sll $0,48,$0
+ and $2,0x1f,$2
+ sra $0,48,$0 /* $0 = disp */
+ get_user_reg($1)
+ mov $3,$1
+ get_user_reg($2) /* $3 = Rb */
+ /* needs writing here */
+ addq $0,$3,$0
+ srl $0,LOG2_TASKSIZE,$5 /* if addr is not in userland, */
+ cmovne $5,$31,$0 /* then force a segfault by putting addr=0 */
+ ldq_u $3,1($0)
+ ldq_u $2,0($0)
+ inswh $1,$0,$5
+ inswl $1,$0,$4
+ mskwh $3,$0,$3
+ mskwl $2,$0,$2
+ or $3,$5,$3
+ or $2,$4,$2
+ stq_u $3,1($0)
+ stq_u $2,0($0)
+
+ ldq $5,40($30)
+ ldq $4,32($30)
+ ldq $3,24($30)
+ ldq $2,16($30)
+ ldq $1,8($30)
+ ldq $0,0($30)
+ addq $30,7*8,$30
+ call_pal PAL_rti
+.end emul_stw
+
+.align 3
+.globl emul_ldbu
+.ent emul_ldbu
+emul_ldbu:
+ stq $3,24($30)
+ stq $4,32($30)
+ stq $5,40($30)
+
+ srl $0,21,$1
+ srl $0,16,$2
+ and $1,0x1f,$1
+ sll $0,48,$0
+ and $2,0x1f,$2
+ sra $0,48,$0 /* $0 = disp */
+ get_user_reg($2) /* $3 = Rb */
+ addq $0,$3,$0
+ srl $0,LOG2_TASKSIZE,$5 /* if addr is not in userland, */
+ cmovne $5,$31,$0 /* then force a segfault by putting addr=0 */
+ ldq_u $3,0($0)
+ extbl $3,$0,$3
+ put_user_reg($1)
+
+ ldq $5,40($30)
+ ldq $4,32($30)
+ ldq $3,24($30)
+ ldq $2,16($30)
+ ldq $1,8($30)
+ ldq $0,0($30)
+ addq $30,7*8,$30
+ call_pal PAL_rti
+.end emul_ldbu
+
+.align 3
+.globl emul_stb
+.ent emul_stb
+emul_stb:
+ stq $3,24($30)
+ stq $4,32($30)
+ stq $5,40($30)
+
+ srl $0,21,$1
+ srl $0,16,$2
+ and $1,0x1f,$1
+ sll $0,48,$0
+ and $2,0x1f,$2
+ sra $0,48,$0 /* $0 = disp */
+ get_user_reg($1)
+ mov $3,$1
+ get_user_reg($2) /* $3 = Rb */
+ addq $0,$3,$0
+ srl $0,LOG2_TASKSIZE,$5 /* if addr is not in userland, */
+ cmovne $5,$31,$0 /* then force a segfault by putting addr=0 */
+ ldq_u $2,0($0)
+ insbl $1,$0,$3
+ mskbl $2,$0,$2
+
+ ldq $5,40($30)
+ or $2,$3,$2
+
+ ldq $3,24($30)
+ stq_u $2,0($0)
+
+ ldq $2,16($30)
+ ldq $1,8($30)
+ ldq $0,0($30)
+ addq $30,7*8,$30
+ call_pal PAL_rti
+.end emul_stb
+
+.align 3
+.globl emul_minsw_4
+.ent emul_minsw_4
+emul_minsw_4:
+ stq $6,48($30)
+
+ extwl $3,0x6,$4 /* get word 3 of ra (most significant) -> $4 */
+ extwl $2,0x6,$1 /* get word 3 of rb -> $2 */
+ cmple $2,$3,$6
+ cmovne $6,$1,$4
+
+ extwl $3,0x4,$5 /* get word 2 of ra -> $5 */
+ extwl $2,0x4,$1 /* get word 2 of rb -> $1 */
+ cmple $2,$3,$6
+ sll $4,16,$4
+ cmovne $6,$1,$5
+ or $4,$5,$4
+
+ extwl $3,0x2,$5 /* get word 1 of ra -> $5 */
+ extwl $2,0x2,$1 /* get word 1 of rb -> $1 */
+ cmple $2,$3,$6
+ sll $4,16,$4
+ cmovne $6,$1,$5
+ or $4,$5,$4
+
+ extwl $3,0x0,$5 /* get word 1 of ra -> $5 */
+ extwl $2,0x0,$1 /* get word 1 of rb -> $1 */
+ cmple $2,$3,$6
+ sll $4,16,$4
+ cmovne $6,$1,$5
+ or $4,$5,$3
+
+ ldq $6,48($30)
+
+ put_user_reg($0)
+
+ ldq $5,40($30)
+ ldq $4,32($30)
+ ldq $3,24($30)
+ ldq $2,16($30)
+ ldq $1,8($30)
+ ldq $0,0($30)
+ addq $30,7*8,$30
+ call_pal PAL_rti
+.end emul_minsw_4
+
+.align 3
+.globl emul_minuw_4
+.ent emul_minuw_4
+emul_minuw_4:
+ stq $6,48($30)
+
+ extwl $3,0x6,$4 /* get word 3 of ra (most significant) -> $4 */
+ extwl $2,0x6,$1 /* get word 3 of rb -> $2 */
+ cmpule $2,$3,$6
+ cmovne $6,$1,$4
+
+ extwl $3,0x4,$5 /* get word 2 of ra -> $5 */
+ extwl $2,0x4,$1 /* get word 2 of rb -> $1 */
+ cmpule $2,$3,$6
+ sll $4,16,$4
+ cmovne $6,$1,$5
+ or $4,$5,$4
+
+ extwl $3,0x2,$5 /* get word 1 of ra -> $5 */
+ extwl $2,0x2,$1 /* get word 1 of rb -> $1 */
+ cmpule $2,$3,$6
+ sll $4,16,$4
+ cmovne $6,$1,$5
+ or $4,$5,$4
+
+ extwl $3,0x0,$5 /* get word 1 of ra -> $5 */
+ extwl $2,0x0,$1 /* get word 1 of rb -> $1 */
+ cmpule $2,$3,$6
+ sll $4,16,$4
+ cmovne $6,$1,$5
+ or $4,$5,$3
+
+ ldq $6,48($30)
+
+ put_user_reg($0)
+
+ ldq $5,40($30)
+ ldq $4,32($30)
+ ldq $3,24($30)
+ ldq $2,16($30)
+ ldq $1,8($30)
+ ldq $0,0($30)
+ addq $30,7*8,$30
+ call_pal PAL_rti
+.end emul_minuw_4
+
+.align 3
+.globl emul_maxsw_4
+.ent emul_maxsw_4
+emul_maxsw_4:
+ stq $6,48($30)
+
+ extwl $3,0x6,$4 /* get word 3 of ra (most significant) -> $4 */
+ extwl $2,0x6,$1 /* get word 3 of rb -> $2 */
+ cmple $4,$1,$6
+ cmovne $6,$1,$4
+
+ extwl $3,0x4,$5 /* get word 2 of ra -> $5 */
+ extwl $2,0x4,$1 /* get word 2 of rb -> $1 */
+ cmple $5,$1,$6
+ sll $4,16,$4
+ cmovne $6,$1,$5
+ or $4,$5,$4
+
+ extwl $3,0x2,$5 /* get word 1 of ra -> $5 */
+ extwl $2,0x2,$1 /* get word 1 of rb -> $1 */
+ cmple $5,$1,$6
+ sll $4,16,$4
+ cmovne $6,$1,$5
+ or $4,$5,$4
+
+ extwl $3,0x0,$5 /* get word 1 of ra -> $5 */
+ extwl $2,0x0,$1 /* get word 1 of rb -> $1 */
+ cmple $5,$1,$6
+ sll $4,16,$4
+ cmovne $6,$1,$5
+ or $4,$5,$3
+
+ ldq $6,48($30)
+
+ put_user_reg($0)
+
+ ldq $5,40($30)
+ ldq $4,32($30)
+ ldq $3,24($30)
+ ldq $2,16($30)
+ ldq $1,8($30)
+ ldq $0,0($30)
+ addq $30,7*8,$30
+ call_pal PAL_rti
+.end emul_maxsw_4
+
+.align 3
+.globl emul_maxuw_4
+.ent emul_maxuw_4
+emul_maxuw_4:
+ stq $6,48($30)
+
+ extwl $3,0x6,$4 /* get word 3 of ra (most significant) -> $4 */
+ extwl $2,0x6,$1 /* get word 3 of rb -> $2 */
+ cmpule $4,$1,$6
+ cmovne $6,$1,$4
+
+ extwl $3,0x4,$5 /* get word 2 of ra -> $5 */
+ extwl $2,0x4,$1 /* get word 2 of rb -> $1 */
+ cmpule $5,$1,$6
+ sll $4,16,$4
+ cmovne $6,$1,$5
+ or $4,$5,$4
+
+ extwl $3,0x2,$5 /* get word 1 of ra -> $5 */
+ extwl $2,0x2,$1 /* get word 1 of rb -> $1 */
+ cmpule $5,$1,$6
+ sll $4,16,$4
+ cmovne $6,$1,$5
+ or $4,$5,$4
+
+ extwl $3,0x0,$5 /* get word 1 of ra -> $5 */
+ extwl $2,0x0,$1 /* get word 1 of rb -> $1 */
+ cmpule $5,$1,$6
+ sll $4,16,$4
+ cmovne $6,$1,$5
+ or $4,$5,$3
+
+ ldq $6,48($30)
+
+ put_user_reg($0)
+
+ ldq $5,40($30)
+ ldq $4,32($30)
+ ldq $3,24($30)
+ ldq $2,16($30)
+ ldq $1,8($30)
+ ldq $0,0($30)
+ addq $30,7*8,$30
+ call_pal PAL_rti
+.end emul_maxuw_4
+
+.align 3
+.globl emul_maxub_8
+.ent emul_maxub_8
+emul_maxub_8:
+ cmpbge $2,$3,$1
+ zap $3,$1,$3
+ zapnot $2,$1,$2
+ or $3,$2,$3
+ put_user_reg($0)
+
+ ldq $5,40($30)
+ ldq $4,32($30)
+ ldq $3,24($30)
+ ldq $2,16($30)
+ ldq $1,8($30)
+ ldq $0,0($30)
+ addq $30,7*8,$30
+ call_pal PAL_rti
+.end emul_maxub_8
+
+.align 3
+.globl emul_maxub_8
+.ent emul_maxub_8
+emul_maxsb_8:
+ lda $1,0x7f7f($31)
+ ldah $1,0x7f7f($1)
+ sll $1,32,$5
+ or $1,$5,$1
+ not $1,$1
+ xor $3,$1,$5
+ xor $2,$1,$1
+
+ cmpbge $1,$5,$1
+ zap $3,$1,$3
+ zapnot $2,$1,$2
+ or $3,$2,$3
+ put_user_reg($0)
+
+ ldq $5,40($30)
+ ldq $4,32($30)
+ ldq $3,24($30)
+ ldq $2,16($30)
+ ldq $1,8($30)
+ ldq $0,0($30)
+ addq $30,7*8,$30
+ call_pal PAL_rti
+.end emul_maxub_8
+
+.align 3
+.globl emul_minub_8
+.ent emul_minub_8
+emul_minub_8:
+ cmpbge $3,$2,$1
+ zap $3,$1,$3
+ zapnot $2,$1,$2
+ or $3,$2,$3
+ put_user_reg($0)
+
+ ldq $5,40($30)
+ ldq $4,32($30)
+ ldq $3,24($30)
+ ldq $2,16($30)
+ ldq $1,8($30)
+ ldq $0,0($30)
+ addq $30,7*8,$30
+ call_pal PAL_rti
+.end emul_minub_8
+
+.align 3
+.globl emul_minsb_8
+.ent emul_minsb_8
+emul_minsb_8:
+ lda $1,0x7f7f($31)
+ ldah $1,0x7f7f($1)
+ sll $1,32,$5
+ or $1,$5,$1
+ not $1,$1
+ xor $3,$1,$5
+ xor $2,$1,$1
+
+ cmpbge $5,$1,$1
+ zap $3,$1,$3
+ zapnot $2,$1,$2
+ or $3,$2,$3
+ put_user_reg($0)
+
+ ldq $5,40($30)
+ ldq $4,32($30)
+ ldq $3,24($30)
+ ldq $2,16($30)
+ ldq $1,8($30)
+ ldq $0,0($30)
+ addq $30,7*8,$30
+ call_pal PAL_rti
+.end emul_minsb_8
+
+.align 3
+.globl emul_sexw
+.ent emul_sexw
+emul_sexw:
+ sll $3,48,$3
+ and $0,0x1f,$1
+ sra $3,48,$3
+ put_user_reg($1)
+ ldq $5,40($30)
+ ldq $4,32($30)
+ ldq $3,24($30)
+ ldq $2,16($30)
+ ldq $1,8($30)
+ ldq $0,0($30)
+ addq $30,7*8,$30
+ call_pal PAL_rti
+.end emul_sexw
+
+.align 3
+.globl emul_sexb
+.ent emul_sexb
+emul_sexb:
+ sll $3,56,$3
+ and $0,0x1f,$1
+ sra $3,56,$3
+ put_user_reg($1)
+ ldq $5,40($30)
+ ldq $4,32($30)
+ ldq $3,24($30)
+ ldq $2,16($30)
+ ldq $1,8($30)
+ ldq $0,0($30)
+ addq $30,7*8,$30
+ call_pal PAL_rti
+.end emul_sexb
+
+.align 3
+.globl emul_mmx
+.ent emul_mmx
+emul_mmx:
+ stq $3,24($30)
+ stq $4,32($30)
+ stq $5,40($30)
+
+ srl $0,5,$4
+ srl $0,12,$2
+ and $4,0x3f,$4
+ blbs $2,21f
+ srl $0,16,$1
+ and $1,0x1f,$1
+ get_user_reg($1)
+21:
+ srl $0,13,$1
+ and $1,0xff,$1
+ cmovlbs $2,$1,$3
+ /* now: $0 = insn
+ $3 = regb val
+ $4 = operation function code */
+ cmpeq $4,0x1,$2
+ beq $4,emul_sexb
+ bne $2,emul_sexw
+ srl $0,21,$1
+ mov $3,$2
+ and $1,0x1f,$1
+ get_user_reg($1)
+ cmpeq $4,0x3a,$1
+ cmpeq $4,0x38,$5
+ and $0,0x1f,$0
+ /* now: $0 = rc index
+ $2 = rb val
+ $3 = ra val
+ $4 = operation function code */
+ bne $1,emul_minub_8
+ bne $5,emul_minsb_8
+ cmpeq $4,0x3e,$1
+ cmpeq $4,0x3c,$5
+ bne $1,emul_maxsb_8
+ bne $5,emul_maxub_8
+ cmpeq $4,0x39,$1
+ cmpeq $4,0x3f,$5
+ bne $1,emul_minsw_4
+ bne $5,emul_maxsw_4
+ cmpeq $4,0x3b,$1
+ cmpeq $4,0x3d,$5
+ bne $1,emul_minuw_4
+ bne $5,emul_maxuw_4
+ ldq $5,40($30)
+ ldq $4,32($30)
+ ldq $3,24($30)
+ ldq $2,16($30)
+ ldq $1,8($30)
+ ldq $0,0($30)
+ addq $30,7*8,$30
+ br old_entIF
+.end emul_mmx
+
+#endif /* CONFIG_ALPHA_EXTINSNS */
+
.align 3
.globl entIF
.ent entIF
entIF:
+#ifdef CONFIG_ALPHA_EXTINSNS
+ subq $30,7*8,$30 /* 3 regs saved here, 3 or 4 more saved in fns */
+ stq $0,0($30)
+ ldq $0,8+7*8($30)
+ stq $1,8($30)
+ ldl $0,-4($0)
+ stq $2,16($30)
+ srl $0,26,$1
+ and $1,0x3f,$1
+ cmpeq $1,0x1c,$2
+ bne $2,emul_mmx
+ cmpeq $1,0x0a,$2
+ bne $2,emul_ldbu
+ cmpeq $1,0x0e,$2
+ bne $2,emul_stb
+ cmpeq $1,0x0c,$2
+ cmpeq $1,0x0d,$1
+ bne $2,emul_ldwu
+ bne $1,emul_stw
+ ldq $0,0($30)
+ ldq $1,8($30)
+ ldq $2,16($30)
+ addq $30,7*8,$30
+old_entIF:
+#endif /* CONFIG_ALPHA_EXTINSNS */
SAVE_ALL
lda $8,0x3fff
lda $26,ret_from_sys_call
\
 
 \ /
  Last update: 2005-03-22 13:54    [W:0.075 / U:0.360 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site