/* $NetBSD: bds_emul.S,v 1.10 2019/04/06 03:06:26 thorpej Exp $ */ /* * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Ralph Campbell. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)fp.s 8.1 (Berkeley) 6/10/93 */ #include #include #include /* for T_RES_INST */ #include #include "assym.h" /* insns are reordered in the way as MIPS architecture imposes */ .set reorder #define REG_REGMASK (0x1f << REG_SCALESHIFT) /* * Emulate CPU instruction in branch delay slot. * These instructions are not implemented and causes SIGILL. * jump/branch * COP0 * trap/syscall/break * * Args are same as mips_emul_fp, eg. * void mips_emul_delayslot(uint32_t insn, struct trapframe *tf, uint32_t cause); * It should be used to emulate an instruction in a branch delay slot. */ LEAF(mips_emul_branchdelayslot) REG_PROLOGUE REG_S zero, TF_REG_ZERO(a1) # ensure zero has value 0 REG_EPILOGUE move t3, ra # need to save this locally srl t0, a0, 26-PTR_SCALESHIFT andi t0, 0x3F << PTR_SCALESHIFT PTR_L t9, bcemul_optbl(t0) jr t9 .rdata bcemul_optbl: PTR_WORD bcemul_special # 000 SPECIAL PTR_WORD bcemul_sigill # 001 REGIMM PTR_WORD bcemul_sigill # 002 J PTR_WORD bcemul_sigill # 003 JAL PTR_WORD bcemul_sigill # 004 BEQ PTR_WORD bcemul_sigill # 005 BNE PTR_WORD bcemul_sigill # 006 BLEZ PTR_WORD bcemul_sigill # 007 BGTZ PTR_WORD bcemul_addi # 010 ADDI PTR_WORD bcemul_addiu # 011 ADDIU PTR_WORD bcemul_slti # 012 SLTI PTR_WORD bcemul_sltiu # 013 SLTIU PTR_WORD bcemul_andi # 014 ANDI PTR_WORD bcemul_ori # 015 ORI PTR_WORD bcemul_xori # 016 XORI PTR_WORD bcemul_lui # 017 LUI PTR_WORD bcemul_sigill # 020 COP0 PTR_WORD _C_LABEL(mips_emul_fp) # 021 COP1 PTR_WORD bcemul_sigill # 022 COP2 PTR_WORD bcemul_sigill # 023 COP1X PTR_WORD bcemul_sigill # 024 BEQL PTR_WORD bcemul_sigill # 025 BNEL PTR_WORD bcemul_sigill # 026 BNEZL PTR_WORD bcemul_sigill # 027 BGTZL #ifdef __mips_o32 PTR_WORD bcemul_sigill # 030 DADDI (*) PTR_WORD bcemul_sigill # 031 DADDIU (*) PTR_WORD bcemul_sigill # 030 LDL (*) PTR_WORD bcemul_sigill # 031 LDR (*) #else PTR_WORD bcemul_daddi # 030 DADDI (*) PTR_WORD bcemul_daddiu # 031 DADDIU (*) PTR_WORD _C_LABEL(mips_emul_ldl) # 032 LDL (*) PTR_WORD _C_LABEL(mips_emul_ldr) # 033 LDR (*) #endif PTR_WORD bcemul_sigill # 034 SPECIAL2 PTR_WORD bcemul_sigill # 035 JALX PTR_WORD bcemul_sigill # 036 MDMX PTR_WORD bcemul_sigill # 037 SPECIAL3 PTR_WORD _C_LABEL(mips_emul_lb) # 040 LB PTR_WORD _C_LABEL(mips_emul_lh) # 041 LH PTR_WORD _C_LABEL(mips_emul_lwl) # 042 LWL PTR_WORD _C_LABEL(mips_emul_lw) # 043 LW PTR_WORD _C_LABEL(mips_emul_lbu) # 044 LBU PTR_WORD _C_LABEL(mips_emul_lhu) # 045 LHU PTR_WORD _C_LABEL(mips_emul_lwr) # 046 LWR #ifdef __mips_o32 PTR_WORD bcemul_sigill # 047 LWU (*) #else PTR_WORD _C_LABEL(mips_emul_lwu) # 047 LWU (*) #endif PTR_WORD _C_LABEL(mips_emul_sb) # 050 SB PTR_WORD _C_LABEL(mips_emul_sh) # 051 SH PTR_WORD _C_LABEL(mips_emul_swl) # 052 SWL PTR_WORD _C_LABEL(mips_emul_sw) # 053 SW #ifdef __mips_o32 PTR_WORD bcemul_sigill # 054 SDL (*) PTR_WORD bcemul_sigill # 055 SDR (*) #else PTR_WORD _C_LABEL(mips_emul_sdl) # 054 SDL (*) PTR_WORD _C_LABEL(mips_emul_sdr) # 055 SDR (*) #endif PTR_WORD _C_LABEL(mips_emul_swr) # 056 SWR PTR_WORD bcemul_sigill # 057 CACHE PTR_WORD bcemul_sigill # 060 LL PTR_WORD _C_LABEL(mips_emul_lwc1) # 061 LWC1 PTR_WORD bcemul_sigill # 062 LWC2 PTR_WORD bcemul_sigill # 063 PREF PTR_WORD bcemul_sigill # 064 LLD (*) PTR_WORD _C_LABEL(mips_emul_ldc1) # 065 LDC PTR_WORD bcemul_sigill # 066 LDC2 #ifdef __mips_o32 PTR_WORD bcemul_sigill # 067 LD (*) #else PTR_WORD _C_LABEL(mips_emul_ld) # 067 LD (*) #endif PTR_WORD bcemul_sigill # 070 SC PTR_WORD _C_LABEL(mips_emul_swc1) # 071 SWC1 PTR_WORD bcemul_sigill # 072 SWC2 PTR_WORD bcemul_sigill # 073 PTR_WORD bcemul_sigill # 074 SCD (*) PTR_WORD _C_LABEL(mips_emul_sdc1) # 075 SDC1 PTR_WORD bcemul_sigill # 076 SDC2 #ifdef __mips_o32 PTR_WORD bcemul_sigill # 077 SD (*) #else PTR_WORD _C_LABEL(mips_emul_sd) # 077 SD (*) #endif .text bcemul_immed_prologue: srl t1, a0, 21-REG_SCALESHIFT # rs (source) srl t2, a0, 16-REG_SCALESHIFT # rt (dest) andi t1, REG_REGMASK andi t2, REG_REGMASK PTR_ADDU t1, a1 PTR_ADDU t2, a1 sll v1, a0, 16 sra v1, v1, 16 # signed immed REG_PROLOGUE REG_L v0, TF_REG_ZERO(t1) # load source REG_EPILOGUE jr ra # execute the instruction bcemul_uimmed_prologue: srl t1, a0, 21-REG_SCALESHIFT # rs (source) srl t2, a0, 16-REG_SCALESHIFT # rt (dest) andi t1, REG_REGMASK andi t2, REG_REGMASK PTR_ADDU t1, a1 PTR_ADDU t2, a1 andi v1, a0, 0xffff # unsigned immed REG_PROLOGUE REG_L v0, TF_REG_ZERO(t1) # load source REG_EPILOGUE jr ra #ifndef __mips_o32 bcemul_daddi: bal bcemul_immed_prologue dadd t0, v0, v1 b bcemul_check_add_overflow #endif bcemul_addi: bal bcemul_immed_prologue addu t0, v0, v1 bcemul_check_add_overflow: move ta0, t0 # result move ta1, v0 # addend 1 move ta2, v1 # addend 2 bcemul_check_overflow: /* Overflow check */ xor ta2, ta1 /* negative + positive can't overflow */ bltz ta2, bcemul_store_and_done /* must have added two positive or two negative numbers */ xor ta1, ta0 /* result have same signedness as source? */ bgez ta1, bcemul_store_and_done /* yes, then we didn't overflow */ b bcemul_sigill bcemul_addiu: bal bcemul_immed_prologue addu t0, v0, v1 b bcemul_store_and_done #ifndef __mips_o32 bcemul_daddiu: bal bcemul_immed_prologue daddu t0, v0, v1 b bcemul_store_and_done #endif bcemul_slti: bal bcemul_immed_prologue slt t0, v0, v1 b bcemul_store_and_done bcemul_sltiu: bal bcemul_immed_prologue sltu t0, v0, v1 b bcemul_store_and_done bcemul_andi: bal bcemul_uimmed_prologue and t0, v0, v1 b bcemul_store_and_done bcemul_ori: bal bcemul_uimmed_prologue or t0, v0, v1 b bcemul_store_and_done bcemul_xori: bal bcemul_uimmed_prologue xor t0, v0, v1 b bcemul_store_and_done bcemul_lui: srl t2, a0, 16-REG_SCALESHIFT # rt andi t2, REG_REGMASK PTR_ADDU t2, a1 sll t0, a0, 16 b bcemul_store_and_done .rdata bcemul_specialtbl: PTR_WORD bcemul_special_genshift # 000 SLL PTR_WORD bcemul_sigill # 001 MOVC1 PTR_WORD bcemul_special_genshift # 002 SRL PTR_WORD bcemul_special_genshift # 003 SRA PTR_WORD bcemul_special_genshiftv # 004 SLLV PTR_WORD bcemul_sigill # 005 PTR_WORD bcemul_special_genshiftv # 006 SRLV PTR_WORD bcemul_special_genshiftv # 007 SRAV PTR_WORD bcemul_sigill # 010 JR PTR_WORD bcemul_sigill # 011 JALR PTR_WORD bcemul_sigill # 012 MOVZ PTR_WORD bcemul_sigill # 013 MOVN PTR_WORD bcemul_sigill # 014 SYSCALL PTR_WORD bcemul_sigill # 015 BREAK PTR_WORD bcemul_sigill # 016 PTR_WORD bcemul_special_sync # 017 SYNC PTR_WORD bcemul_special_mfhilo # 020 MFHI PTR_WORD bcemul_special_mthilo # 021 MTHI PTR_WORD bcemul_special_mfhilo # 022 MFLO PTR_WORD bcemul_special_mthilo # 023 MTLO #ifdef __mips_o32 PTR_WORD bcemul_sigill # 024 DSLLV (*) PTR_WORD bcemul_sigill # 025 PTR_WORD bcemul_sigill # 026 DSRLV (*) PTR_WORD bcemul_sigill # 027 DSRAV (*) #else PTR_WORD bcemul_special_genshiftv # 024 DSLLV (*) PTR_WORD bcemul_sigill # 025 PTR_WORD bcemul_special_genshiftv # 026 DSRLV (*) PTR_WORD bcemul_special_genshiftv # 027 DSRAV (*) #endif PTR_WORD bcemul_special_genmultdiv # 030 MULT PTR_WORD bcemul_special_genmultdiv # 031 MULTU PTR_WORD bcemul_special_genmultdiv # 032 DIV PTR_WORD bcemul_special_genmultdiv # 033 DIVU #ifdef __mips_o32 PTR_WORD bcemul_sigill # 034 DMULT (*) PTR_WORD bcemul_sigill # 035 DMULTU (*) PTR_WORD bcemul_sigill # 036 DDIV (*) PTR_WORD bcemul_sigill # 037 DDIVU (*) #else PTR_WORD bcemul_special_genmultdiv # 034 DMULT (*) PTR_WORD bcemul_special_genmultdiv # 035 DMULTU (*) PTR_WORD bcemul_special_genmultdiv # 036 DDIV (*) PTR_WORD bcemul_special_genmultdiv # 037 DDIVU (*) #endif PTR_WORD bcemul_special_genadd # 040 ADD PTR_WORD bcemul_special_gen3op # 041 ADDU PTR_WORD bcemul_special_gensub # 042 SUB PTR_WORD bcemul_special_gen3op # 043 SUBU PTR_WORD bcemul_special_gen3op # 044 AND PTR_WORD bcemul_special_gen3op # 045 OR PTR_WORD bcemul_special_gen3op # 046 XOR PTR_WORD bcemul_special_gen3op # 047 NOR PTR_WORD bcemul_sigill # 050 PTR_WORD bcemul_sigill # 051 PTR_WORD bcemul_special_gen3op # 052 SLT PTR_WORD bcemul_special_gen3op # 053 SLTU #ifdef __mips_o32 PTR_WORD bcemul_sigill # 054 DADD (*) PTR_WORD bcemul_sigill # 055 DADDU (*) PTR_WORD bcemul_sigill # 056 DSUB (*) PTR_WORD bcemul_sigill # 057 DSUBU (*) #else PTR_WORD bcemul_special_genadd # 054 DADD (*) PTR_WORD bcemul_special_gen3op # 055 DADDU (*) PTR_WORD bcemul_special_gensub # 056 DSUB (*) PTR_WORD bcemul_special_gen3op # 057 DSUBU (*) #endif PTR_WORD bcemul_sigill # 060 TGE PTR_WORD bcemul_sigill # 061 TGEU PTR_WORD bcemul_sigill # 062 TLT PTR_WORD bcemul_sigill # 063 TLTU PTR_WORD bcemul_sigill # 064 TEQ PTR_WORD bcemul_sigill # 065 PTR_WORD bcemul_sigill # 066 TNE PTR_WORD bcemul_sigill # 067 #ifdef __mips_o32 PTR_WORD bcemul_sigill # 070 DSLL (*) PTR_WORD bcemul_sigill # 071 PTR_WORD bcemul_sigill # 072 DSRL (*) PTR_WORD bcemul_sigill # 073 DSRA (*) PTR_WORD bcemul_sigill # 074 DSLL32 (*) PTR_WORD bcemul_sigill # 075 PTR_WORD bcemul_sigill # 076 DSRL32 (*) PTR_WORD bcemul_sigill # 077 DSRA32 (*) #else PTR_WORD bcemul_special_genshift # 070 DSLL (*) PTR_WORD bcemul_sigill # 071 PTR_WORD bcemul_special_genshift # 072 DSRL (*) PTR_WORD bcemul_special_genshift # 073 DSRA (*) PTR_WORD bcemul_special_genshift # 074 DSLL32 (*) PTR_WORD bcemul_sigill # 075 PTR_WORD bcemul_special_genshift # 076 DSRL32 (*) PTR_WORD bcemul_special_genshift # 077 DSRA32 (*) #endif .text .set push .set noreorder .set nomacro .set mips64 bcemul_special_op: jr ra; sllv t0, v0, v1 # 000 SLL jr ra; nop # 001 MOVC1 jr ra; srlv t0, v0, v1 # 002 SRL jr ra; srav t0, v0, v1 # 003 SRA jr ra; sllv t0, v0, v1 # 004 SLLV jr ra; nop # 005 * jr ra; srlv t0, v0, v1 # 006 SRLV jr ra; srav t0, v0, v1 # 007 SRAV jr ra; nop # 010 JR jr ra; nop # 011 JALR jr ra; movz t0, v0, v1 # 012 MOVZ jr ra; movn t0, v0, v1 # 013 MOVN jr ra; nop # 014 SYSCALL jr ra; nop # 015 BREAK jr ra; nop # 016 * jr ra; nop # 017 SYNC jr ra; mfhi t0 # 020 MFHI jr ra; mthi v0 # 021 MTHI jr ra; mflo t0 # 022 MFLO jr ra; mtlo v0 # 023 MTLO jr ra; dsllv t0, v0, v1 # 024 DSLLV jr ra; nop # 025 * jr ra; dsrlv t0, v0, v1 # 026 DSRLV jr ra; dsrav t0, v0, v1 # 027 DSRAV jr ra; mult v0, v1 # 030 MULT jr ra; multu v0, v1 # 031 MULTU jr ra; div $0, v0, v1 # 032 DIV jr ra; divu $0, v0, v1 # 033 DIVU jr ra; dmult v0, v1 # 034 DMULT jr ra; dmultu v0, v1 # 035 DMULTU jr ra; ddiv $0, v0, v1 # 036 DDIV jr ra; ddivu $0, v0, v1 # 037 DDIVU jr ra; add t0, v0, v1 # 040 ADD jr ra; addu t0, v0, v1 # 041 ADDU jr ra; sub t0, v0, v1 # 042 SUB jr ra; subu t0, v0, v1 # 043 SUBU jr ra; and t0, v0, v1 # 044 AND jr ra; or t0, v0, v1 # 045 OR jr ra; xor t0, v0, v1 # 046 XOR jr ra; nor t0, v0, v1 # 047 NOR jr ra; nop # 050 * jr ra; nop # 051 * jr ra; slt t0, v0, v1 # 052 SLT jr ra; sltu t0, v0, v1 # 053 SLTU jr ra; dadd t0, v0, v1 # 054 DADD jr ra; daddu t0, v0, v1 # 055 DADDU jr ra; dsub t0, v0, v1 # 056 DSUB jr ra; dsubu t0, v0, v1 # 057 DSUBU jr ra; tge v0, v1 # 060 TGE jr ra; tgeu v0, v1 # 061 TGEU jr ra; tlt v0, v1 # 062 TLT jr ra; tltu v0, v1 # 063 TLTU jr ra; teq v0, v1 # 064 TEQ jr ra; nop # 065 * jr ra; tne v0, v1 # 066 TNE jr ra; nop # 067 * jr ra; dsllv t0, v0, v1 # 070 DSLL jr ra; nop # 071 * jr ra; dsrlv t0, v0, v1 # 072 DSRL jr ra; dsrav t0, v0, v1 # 073 DSRA jr ra; dsllv t0, v0, v1 # 074 DSLL32 jr ra; nop # 075 * jr ra; dsrlv t0, v0, v1 # 076 DSRL32 jr ra; dsrav t0, v0, v1 # 077 DSRA32 .set pop bcemul_special: andi t0, a0, 0x3f # get special code sll t1, t0, 3 # calculate index in specialop sll t0, PTR_SCALESHIFT PTR_L t9, bcemul_specialtbl(t0) PTR_LA t0, bcemul_special_op(t1) jr t9 bcemul_special_3op_prologue: move t9, t0 srl t0, a0, 21-REG_SCALESHIFT # rs (source1) srl t1, a0, 16-REG_SCALESHIFT # rt (source2) srl t2, a0, 11-REG_SCALESHIFT # rd (dest) andi t0, REG_REGMASK andi t1, REG_REGMASK andi t2, REG_REGMASK PTR_ADDU t0, a1 PTR_ADDU t1, a1 PTR_ADDU t2, a1 REG_PROLOGUE REG_L v0, TF_REG_ZERO(t0) # load source1 REG_L v1, TF_REG_ZERO(t1) # load source2 REG_EPILOGUE jr t9 bcemul_special_2src_prologue: move t9, t0 srl t0, a0, 21-REG_SCALESHIFT # rs (source1) srl t1, a0, 16-REG_SCALESHIFT # rt (source2) andi t0, REG_REGMASK andi t1, REG_REGMASK PTR_ADDU t0, a1 PTR_ADDU t1, a1 REG_PROLOGUE REG_L v0, TF_REG_ZERO(t0) # load source1 REG_L v1, TF_REG_ZERO(t1) # load source2 REG_EPILOGUE jr t9 bcemul_special_genshift: move t9, t0 srl t1, a0, 16-REG_SCALESHIFT # rt (source) srl t2, a0, 11-REG_SCALESHIFT # rd (dest) srl v1, a0, 6 # sa andi t1, REG_REGMASK andi t2, REG_REGMASK beqz t2, bcemul_done # fast escape for nop variants andi v1, 0x001F #ifndef __mips_o32 /* * Deal with DSLL32, DSRA32, DSRL32 who need 32 added to their * shift count. */ andi v0, a0, 077 # focus on special op sltiu v0, v0, 074 # less than DSLL32? xori v0, 1 # invert result sll v0, 5 # shift by 5 (now 0 or 32) addu v1, v0 # add to shift count #endif PTR_ADDU t1, a1 PTR_ADDU t2, a1 REG_PROLOGUE REG_L v0, TF_REG_ZERO(t1) # load source REG_EPILOGUE jal t9 j bcemul_store_and_done bcemul_special_sync: b bcemul_done bcemul_special_mfhilo: srl t2, a0, 11-REG_SCALESHIFT # rd (dest) andi t2, REG_REGMASK PTR_ADDU t1, a1, TF_REG_MULHI PTR_ADDU t2, a1 and v0, a0, 2 # bit 1: 0=HI 1=LO sll v0, REG_SCALESHIFT - 1 #if TF_REG_MULLO < TF_REG_MULHI PTR_SUBU t1, v0 #else PTR_ADDU t1, v0 #endif REG_PROLOGUE REG_L t0, TF_REG_ZERO(t1) # load source (mullo or mulhi) REG_EPILOGUE b bcemul_store_and_done bcemul_special_mthilo: srl t1, a0, 21-REG_SCALESHIFT # rs (source) andi t1, REG_REGMASK PTR_ADDU t1, a1 PTR_ADDU t2, a1, TF_REG_MULHI and v0, a0, 2 # bit 1: 0=HI l=LO sll v0, REG_SCALESHIFT - 1 #if TF_REG_MULLO < TF_REG_MULHI PTR_SUBU t2, v0 #else PTR_ADDU t2, v0 #endif REG_PROLOGUE REG_L t0, TF_REG_ZERO(t1) REG_EPILOGUE b bcemul_store_and_done bcemul_special_genmultdiv: bal bcemul_special_2src_prologue # grab operands and do it. mflo v0 mfhi v1 REG_PROLOGUE REG_S v0, TF_REG_MULLO(a1) REG_S v1, TF_REG_MULHI(a1) REG_EPILOGUE b bcemul_done bcemul_special_genadd: bal bcemul_special_3op_prologue b bcemul_check_add_overflow bcemul_special_gensub: bal bcemul_special_3op_prologue /* * t0 = v0 - v1 which means v0 = t0 + v1 * Now we can the same logic for overflow from addition. */ move ta0, v0 move ta1, t0 move ta2, v1 b bcemul_check_overflow bcemul_special_genshiftv: bcemul_special_gen3op: bal bcemul_special_3op_prologue #b bcemul_store_and_done # fallthrough to bcemul_store_and_done bcemul_store_and_done: beq a1, t2, bcemul_done # don't store to zero REG_PROLOGUE REG_S t0, TF_REG_ZERO(t2) REG_EPILOGUE #b bcemul_done # fallthrough to bcemul_done bcemul_done: /* * Succeeded to emulate instruction with no error * so compute the next PC. */ PTR_SUBU sp, CALLFRAME_SIZ REG_S t3, CALLFRAME_RA(sp) REG_S s0, CALLFRAME_S0(sp) move s0, a1 # save trapfame /* Fetch previous branch instruction */ REG_PROLOGUE REG_L a0, TF_REG_EPC(s0) REG_EPILOGUE jal _C_LABEL(mips_ufetch32) /* Calculate branch destination */ sll t0, v0, 16 sra t0, t0, 16-2 REG_PROLOGUE REG_L t1, TF_REG_EPC(s0) PTR_ADDU t0, 4 PTR_ADDU t1, t0 REG_S t1, TF_REG_EPC(s0) REG_EPILOGUE REG_L ra, CALLFRAME_RA(sp) REG_L s0, CALLFRAME_S0(sp) PTR_ADDU sp, CALLFRAME_SIZ jr ra /* * Send SIGILL, SIGFPE. * Args are same as mips_emul_fp. */ bcemul_sigill: li t0, 0xFFFFFF00 and a2, a2, t0 ori a2, a2, T_RES_INST << MIPS_CR_EXC_CODE_SHIFT REG_PROLOGUE REG_S a2, TF_REG_CAUSE(a1) REG_EPILOGUE move ra, t3 # restore ra move a1, a0 # code = instruction move a0, MIPS_CURLWP # get current process j _C_LABEL(mips_fpuillinst) END(mips_emul_branchdelayslot)