/* * fp_cond.S * * Copyright Roman Zippel, 1997. All rights reserved. * * 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, and the entire permission notice in its entirety, * including the disclaimer of warranties. * 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. The name of the author may not be used to endorse or promote * products derived from this software without specific prior * written permission. * * ALTERNATIVELY, this product may be distributed under the terms of * the GNU General Public License, in which case the provisions of the GPL are * required INSTEAD OF the above restrictions. (This clause is * necessary due to a potential bad interaction between the GPL and * the restrictions contained in a BSD-style copyright.) * * THIS SOFTWARE IS PROVIDED ``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 AUTHOR 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. */ #include "fp_emu.h" #include "fp_decode.h" .globl fp_fscc, fp_fbccw, fp_fbccl #ifdef FPU_EMU_DEBUG fp_fnop: printf PDECODE,"fnop\n" jra fp_end #else #define fp_fnop fp_end #endif fp_fbccw: tst.w %d2 jeq fp_fnop printf PDECODE,"fbccw " fp_get_pc %a0 lea (-2,%a0,%d2.w),%a0 jra 1f fp_fbccl: printf PDECODE,"fbccl " fp_get_pc %a0 move.l %d2,%d0 swap %d0 fp_get_instr_word %d0,fp_err_ua1 lea (-2,%a0,%d0.l),%a0 1: printf PDECODE,"%x",1,%a0 move.l %d2,%d0 swap %d0 jsr fp_compute_cond tst.l %d0 jeq 1f fp_put_pc %a0,1 1: printf PDECODE,"\n" jra fp_end fp_fdbcc: printf PDECODE,"fdbcc " fp_get_pc %a1 | calculate new pc fp_get_instr_word %d0,fp_err_ua1 add.w %d0,%a1 fp_decode_addr_reg printf PDECODE,"d%d,%x\n",2,%d0,%a1 swap %d1 | test condition in %d1 tst.w %d1 jne 2f move.l %d0,%d1 jsr fp_get_data_reg subq.w #1,%d0 jcs 1f fp_put_pc %a1,1 1: jsr fp_put_data_reg 2: jra fp_end | set flags for decode macros for fs do_fscc=1 do_no_pc_mode=1 fp_fscc: printf PDECODE,"fscc " move.l %d2,%d0 jsr fp_compute_cond move.w %d0,%d1 swap %d1 | decode addressing mode fp_decode_addr_mode .long fp_data, fp_fdbcc .long fp_indirect, fp_postinc .long fp_predecr, fp_disp16 .long fp_extmode0, fp_extmode1 | addressing mode: data register direct fp_data: fp_mode_data_direct move.w %d0,%d1 | save register nr jsr fp_get_data_reg swap %d1 move.b %d1,%d0 swap %d1 jsr fp_put_data_reg printf PDECODE,"\n" jra fp_end fp_indirect: fp_mode_addr_indirect jra fp_do_scc fp_postinc: fp_mode_addr_indirect_postinc jra fp_do_scc fp_predecr: fp_mode_addr_indirect_predec jra fp_do_scc fp_disp16: fp_mode_addr_indirect_disp16 jra fp_do_scc fp_extmode0: fp_mode_addr_indirect_extmode0 jra fp_do_scc fp_extmode1: bfextu %d2{#13,#3},%d0 jmp ([0f:w,%pc,%d0*4]) .align 4 0: .long fp_absolute_short, fp_absolute_long .long fp_ill, fp_ill | NOTE: jump here to ftrap.x .long fp_ill, fp_ill .long fp_ill, fp_ill fp_absolute_short: fp_mode_abs_short jra fp_do_scc fp_absolute_long: fp_mode_abs_long | jra fp_do_scc fp_do_scc: swap %d1 putuser.b %d1,(%a0),fp_err_ua1,%a0 printf PDECODE,"\n" jra fp_end #define tst_NAN btst #24,%d1 #define tst_Z btst #26,%d1 #define tst_N btst #27,%d1 fp_compute_cond: move.l (FPD_FPSR,FPDATA),%d1 btst #4,%d0 jeq 1f tst_NAN jeq 1f bset #15,%d1 bset #7,%d1 move.l %d1,(FPD_FPSR,FPDATA) 1: and.w #0xf,%d0 jmp ([0f:w,%pc,%d0.w*4]) .align 4 0: .long fp_f , fp_eq , fp_ogt, fp_oge .long fp_olt, fp_ole, fp_ogl, fp_or .long fp_un , fp_ueq, fp_ugt, fp_uge .long fp_ult, fp_ule, fp_ne , fp_t fp_f: moveq #0,%d0 rts fp_eq: moveq #0,%d0 tst_Z jeq 1f moveq #-1,%d0 1: rts fp_ogt: moveq #0,%d0 tst_NAN jne 1f tst_Z jne 1f tst_N jne 1f moveq #-1,%d0 1: rts fp_oge: moveq #-1,%d0 tst_Z jne 2f tst_NAN jne 1f tst_N jeq 2f 1: moveq #0,%d0 2: rts fp_olt: moveq #0,%d0 tst_NAN jne 1f tst_Z jne 1f tst_N jeq 1f moveq #-1,%d0 1: rts fp_ole: moveq #-1,%d0 tst_Z jne 2f tst_NAN jne 1f tst_N jne 2f 1: moveq #0,%d0 2: rts fp_ogl: moveq #0,%d0 tst_NAN jne 1f tst_Z jne 1f moveq #-1,%d0 1: rts fp_or: moveq #0,%d0 tst_NAN jne 1f moveq #-1,%d0 1: rts fp_un: moveq #0,%d0 tst_NAN jeq 1f moveq #-1,%d0 rts fp_ueq: moveq #-1,%d0 tst_NAN jne 1f tst_Z jne 1f moveq #0,%d0 1: rts fp_ugt: moveq #-1,%d0 tst_NAN jne 2f tst_N jne 1f tst_Z jeq 2f 1: moveq #0,%d0 2: rts fp_uge: moveq #-1,%d0 tst_NAN jne 1f tst_Z jne 1f tst_N jeq 1f moveq #0,%d0 1: rts fp_ult: moveq #-1,%d0 tst_NAN jne 2f tst_Z jne 1f tst_N jne 2f 1: moveq #0,%d0 2: rts fp_ule: moveq #-1,%d0 tst_NAN jne 1f tst_Z jne 1f tst_N jne 1f moveq #0,%d0 1: rts fp_ne: moveq #0,%d0 tst_Z jne 1f moveq #-1,%d0 1: rts fp_t: moveq #-1,%d0 rts