- NBWL M_DREG M_AM_NONE %11100010ss000rrS m_reg +
- NW C_ALTMEM M_AM_NONE %1110000011eee000 m_ea
-bcc NBW C_LABEL M_AM_NONE %01100100bbbbbbbb m_br
+bcc NBWS C_LABEL M_AM_NONE %01100100bbbbbbbb m_br +
bhs
-bcs NBW C_LABEL M_AM_NONE %01100101bbbbbbbb m_br
+- L C_LABEL M_AM_NONE %0110010011111111 m_br30
+bcs NBWS C_LABEL M_AM_NONE %01100101bbbbbbbb m_br +
blo
-beq NBW C_LABEL M_AM_NONE %01100111bbbbbbbb m_br
+- L C_LABEL M_AM_NONE %0110010111111111 m_br30
+beq NBWS C_LABEL M_AM_NONE %01100111bbbbbbbb m_br +
bze
bz
-bge NBW C_LABEL M_AM_NONE %01101100bbbbbbbb m_br
-bgt NBW C_LABEL M_AM_NONE %01101110bbbbbbbb m_br
-bhi NBW C_LABEL M_AM_NONE %01100010bbbbbbbb m_br
-ble NBW C_LABEL M_AM_NONE %01101111bbbbbbbb m_br
-bls NBW C_LABEL M_AM_NONE %01100011bbbbbbbb m_br
-blt NBW C_LABEL M_AM_NONE %01101101bbbbbbbb m_br
-bmi NBW C_LABEL M_AM_NONE %01101011bbbbbbbb m_br
-bne NBW C_LABEL M_AM_NONE %01100110bbbbbbbb m_br
+- L C_LABEL M_AM_NONE %0110011111111111 m_br30
+bge NBWS C_LABEL M_AM_NONE %01101100bbbbbbbb m_br +
+- L C_LABEL M_AM_NONE %0110110011111111 m_br30
+bgt NBWS C_LABEL M_AM_NONE %01101110bbbbbbbb m_br +
+- L C_LABEL M_AM_NONE %0110111011111111 m_br30
+bhi NBWS C_LABEL M_AM_NONE %01100010bbbbbbbb m_br +
+- L C_LABEL M_AM_NONE %0110001011111111 m_br30
+ble NBWS C_LABEL M_AM_NONE %01101111bbbbbbbb m_br +
+- L C_LABEL M_AM_NONE %0110111111111111 m_br30
+bls NBWS C_LABEL M_AM_NONE %01100011bbbbbbbb m_br +
+- L C_LABEL M_AM_NONE %0110001111111111 m_br30
+blt NBWS C_LABEL M_AM_NONE %01101101bbbbbbbb m_br +
+- L C_LABEL M_AM_NONE %0110110111111111 m_br30
+bmi NBWS C_LABEL M_AM_NONE %01101011bbbbbbbb m_br +
+- L C_LABEL M_AM_NONE %0110101111111111 m_br30
+bne NBWS C_LABEL M_AM_NONE %01100110bbbbbbbb m_br +
bnz
-bpl NBW C_LABEL M_AM_NONE %01101010bbbbbbbb m_br
-bvc NBW C_LABEL M_AM_NONE %01101000bbbbbbbb m_br
-bvs NBW C_LABEL M_AM_NONE %01101001bbbbbbbb m_br
+- L C_LABEL M_AM_NONE %01100110bbbbbbbb m_br30
+bpl NBWS C_LABEL M_AM_NONE %01101010bbbbbbbb m_br +
+- L C_LABEL M_AM_NONE %0110101011111111 m_br30
+bvc NBWS C_LABEL M_AM_NONE %01101000bbbbbbbb m_br +
+- L C_LABEL M_AM_NONE %0110100011111111 m_br30
+bvs NBWS C_LABEL M_AM_NONE %01101001bbbbbbbb m_br +
+- L C_LABEL M_AM_NONE %0110100111111111 m_br30
bchg NL M_DREG M_DREG %0000rrr101eeeeee m_bitop +
- NB M_DREG C_ALTDATA %0000rrr101eeeeee m_bitop +
- NL M_IMMED M_DREG %0000100010eeeeee m_bitop +
- NB M_IMMED C_ALTDATA %0000100010eeeeee m_bitop
-bra NBW C_LABEL M_AM_NONE %01100000bbbbbbbb m_br
+bfchg N C_ALL030+M_BITFLD M_AM_NONE %1110101011eeeeee m_bfop
+bfclr N C_ALL030+M_BITFLD M_AM_NONE %1110110011eeeeee m_bfop
+bfexts N C_ALL030+M_BITFLD M_DREG %1110101111eeeeee m_bfop
+bfextu N C_ALL030+M_BITFLD M_DREG %1110100111eeeeee m_bfop
+bfffo N C_ALL030+M_BITFLD M_DREG %1110110111eeeeee m_bfop
+bfins N M_DREG C_ALL030+M_BITFLD %1110111111eeeeee m_bfop
+bfset N C_ALL030+M_BITFLD M_AM_NONE %1110111011eeeeee m_bfop
+bftst N C_ALL030+M_BITFLD M_AM_NONE %1110100011eeeeee m_bfop
+bkpt N M_IMMED M_AM_NONE %0100100001001bbb m_bkpt
+
+bra NBWS C_LABEL M_AM_NONE %01100000bbbbbbbb m_br +
+- L C_LABEL M_AM_NONE %0110000011111111 m_br30
bt
bset NL M_DREG M_DREG %0000rrr111eeeeee m_bitop +
- NL M_IMMED M_DREG %0000100011eeeeee m_bitop +
- NB M_IMMED C_ALTDATA %0000100011eeeeee m_bitop
-bsr NBW C_LABEL M_AM_NONE %01100001bbbbbbbb m_br
+bsr NBWS C_LABEL M_AM_NONE %01100001bbbbbbbb m_br +
+- L C_LABEL M_AM_NONE %0110000111111111 m_br30
btst NL M_DREG M_DREG %0000rrr100eeeeee m_bitop +
- NB M_DREG C_DATA %0000rrr100eeeeee m_bitop +
- NL M_IMMED M_DREG %0000100000eeeeee m_bitop +
- NB M_IMMED C_DATA-M_IMMED %0000100000eeeeee m_bitop
-chk NW C_DATA M_DREG %0100rrr110eR1000 m_ea
+callm N M_IMMED C_ALL030 %0000011011eeeeee m_callm
+
+cas ! M_AM_NONE M_AM_NONE %00001ss011eeeeee m_cas
+cas2 ! M_AM_NONE M_AM_NONE %00001ss011111100 m_cas2
+
+chk NW C_DATA M_DREG %0100rrr110eR1000 m_ea +
+- L C_DATA030 M_DREG %0100rrr100eeeeee m_ea030
+
+cinvl N CACHES M_AIND %11110100cc001rrr m_cinv
+cinvp N CACHES M_AIND %11110100cc010rrr m_cinv
+cinva N CACHES M_AM_NONE %11110100cc011rrr m_cinv
+
+chk2 NBWL C_DATA M_DREG+M_AREG %00000ss011eeeeee m_chk2
clr NBWL C_ALTDATA M_AM_NONE %01000010sseeeS00 m_ea +
- NWL M_AREG M_AM_NONE %1001rrrs11001rrr m_clra
cmpi NBWL M_IMMED C_ALTDATA %00001100sseeeS11 m_ea +
cmpm NBWL M_APOSTINC M_APOSTINC %1011xxx1ss001yRS m_reg
+cmp2 NBWL C_ALL030 M_DREG+M_AREG %00000ss011eeeeee m_cmp2
+
+cpbeq NBW C_LABEL M_AM_NONE %111100101s000001 m_cpbr
+cpbze
+cpbz
+cpbge NBW C_LABEL M_AM_NONE %111100101s010011 m_cpbr
+cpbgt NBW C_LABEL M_AM_NONE %111100101s010010 m_cpbr
+cpbgl NBW C_LABEL M_AM_NONE %111100101s010110 m_cpbr
+cpbgle NBW C_LABEL M_AM_NONE %111100101s010111 m_cpbr
+cpble NBW C_LABEL M_AM_NONE %111100101s010101 m_cpbr
+cpblt NBW C_LABEL M_AM_NONE %111100101s010100 m_cpbr
+cpbne NBW C_LABEL M_AM_NONE %111100101s001110 m_cpbr
+cpbngt NBW C_LABEL M_AM_NONE %111100101s011101 m_cpbr
+cpbnge NBW C_LABEL M_AM_NONE %111100101s011100 m_cpbr
+cpbngl NBW C_LABEL M_AM_NONE %111100101s011001 m_cpbr
+cpbnle NBW C_LABEL M_AM_NONE %111100101s011010 m_cpbr
+cpbngle NBW C_LABEL M_AM_NONE %111100101s011000 m_cpbr
+cpbnz
+cpbogt NBW C_LABEL M_AM_NONE %111100101s000010 m_cpbr
+cpbule NBW C_LABEL M_AM_NONE %111100101s001101 m_cpbr
+cpboge NBW C_LABEL M_AM_NONE %111100101s000011 m_cpbr
+cpbult NBW C_LABEL M_AM_NONE %111100101s001100 m_cpbr
+cpbolt NBW C_LABEL M_AM_NONE %111100101s000100 m_cpbr
+cpbuge NBW C_LABEL M_AM_NONE %111100101s001011 m_cpbr
+cpbole NBW C_LABEL M_AM_NONE %111100101s000101 m_cpbr
+cpbugt NBW C_LABEL M_AM_NONE %111100101s001010 m_cpbr
+cpbogl NBW C_LABEL M_AM_NONE %111100101s000110 m_cpbr
+cpbueq NBW C_LABEL M_AM_NONE %111100101s001001 m_cpbr
+cpbor NBW C_LABEL M_AM_NONE %111100101s000111 m_cpbr
+cpbun NBW C_LABEL M_AM_NONE %111100101s001000 m_cpbr
+cpbt NBW C_LABEL M_AM_NONE %111100101s001111 m_cpbr
+cpbra
+cpbf NBW C_LABEL M_AM_NONE %111100101s000000 m_cpbr
+cpbsf NBW C_LABEL M_AM_NONE %111100101s010000 m_cpbr
+cpbst NBW C_LABEL M_AM_NONE %111100101s011111 m_cpbr
+cpbseq NBW C_LABEL M_AM_NONE %111100101s010001 m_cpbr
+cpbsne NBW C_LABEL M_AM_NONE %111100101s011110 m_cpbr
+
+cpdbeq NBW M_DREG C_LABEL %111100101s000001 m_cpbr
+cpdbze
+cpdbz
+cpdbge NBW M_DREG C_LABEL %111100101s010011 m_cpdbr
+cpdbgt NBW M_DREG C_LABEL %111100101s010010 m_cpdbr
+cpdbgl NBW M_DREG C_LABEL %111100101s010110 m_cpdbr
+cpdbgle NBW M_DREG C_LABEL %111100101s010111 m_cpdbr
+cpdble NBW M_DREG C_LABEL %111100101s010101 m_cpdbr
+cpdblt NBW M_DREG C_LABEL %111100101s010100 m_cpdbr
+cpdbne NBW M_DREG C_LABEL %111100101s001110 m_cpdbr
+cpdbngt NBW M_DREG C_LABEL %111100101s011101 m_cpdbr
+cpdbnge NBW M_DREG C_LABEL %111100101s011100 m_cpdbr
+cpdbngl NBW M_DREG C_LABEL %111100101s011001 m_cpdbr
+cpdbnle NBW M_DREG C_LABEL %111100101s011010 m_cpdbr
+cpdbngle NBW M_DREG C_LABEL %111100101s011000 m_cpdbr
+cpdbnz
+cpdbogt NBW M_DREG C_LABEL %111100101s000010 m_cpdbr
+cpdbule NBW M_DREG C_LABEL %111100101s001101 m_cpdbr
+cpdboge NBW M_DREG C_LABEL %111100101s000011 m_cpdbr
+cpdbult NBW M_DREG C_LABEL %111100101s001100 m_cpdbr
+cpdbolt NBW M_DREG C_LABEL %111100101s000100 m_cpdbr
+cpdbuge NBW M_DREG C_LABEL %111100101s001011 m_cpdbr
+cpdbole NBW M_DREG C_LABEL %111100101s000101 m_cpdbr
+cpdbugt NBW M_DREG C_LABEL %111100101s001010 m_cpdbr
+cpdbogl NBW M_DREG C_LABEL %111100101s000110 m_cpdbr
+cpdbueq NBW M_DREG C_LABEL %111100101s001001 m_cpdbr
+cpdbor NBW M_DREG C_LABEL %111100101s000111 m_cpdbr
+cpdbun NBW M_DREG C_LABEL %111100101s001000 m_cpdbr
+cpdbt NBW M_DREG C_LABEL %111100101s001111 m_cpdbr
+cpdbra
+cpdbf NBW M_DREG C_LABEL %111100101s000000 m_cpdbr
+cpdbsf NBW M_DREG C_LABEL %111100101s010000 m_cpdbr
+cpdbst NBW M_DREG C_LABEL %111100101s011111 m_cpdbr
+cpdbseq NBW M_DREG C_LABEL %111100101s010001 m_cpdbr
+cpdbsne NBW M_DREG C_LABEL %111100101s011110 m_cpdbr
+
+cprestore N C_ALL030 M_AM_NONE %1111001101eeeeee m_cprest
+cpsave N C_ALL030 M_AM_NONE %1111001100eeeeee m_cprest
+
+cpushl N CACHES M_AIND %11110100cc001rrr m_cinv
+cpushp N CACHES M_AIND %11110100cc010rrr m_cinv
+cpusha N CACHES M_AM_NONE %11110100cc011rrr m_cinv
+
dbcc NW M_DREG C_LABEL %0101010011001rrr m_dbra
dbcs NW M_DREG C_LABEL %0101010111001rrr m_dbra
dblo
dbvc NW M_DREG C_LABEL %0101100011001rrr m_dbra
dbvs NW M_DREG C_LABEL %0101100111001rrr m_dbra
-divs NW C_DATA M_DREG %1000rrr111eR1000 m_ea
+divs NW C_DATA M_DREG %1000rrr111eR1000 m_ea +
+- L C_DATA030 M_DREG %0100110001eeeeee m_divs +
+- L C_DATA030 M_DREG %0100110001eeeeee m_divs
+
+divsl NL C_DATA030 M_DREG %0100110001eeeeee m_divsl
-divu NW C_DATA M_DREG %1000rrr011eR1000 m_ea
+divu NW C_DATA M_DREG %1000rrr011eR1000 m_ea +
+- L C_DATA030 M_DREG %0100110001eeeeee m_divu +
+- L C_DATA030 M_DREG %0100110001eeeeee m_divu +
+
+divul LN C_DATA030 M_DREG %0100110001eeeeee m_divul
eor NBWL M_DREG C_ALTDATA %1011rrr1sseR0S01 m_ea +
eori NBWL M_IMMED C_ALTDATA %00001010sseeeS11 m_ea +
ext NW M_DREG M_AM_NONE %0100100010000rrr m_reg +
- L M_DREG M_AM_NONE %0100100011000rrr m_reg
+extb NL M_DREG M_AM_NONE %0100100111000rrr m_reg
+
+fabs NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_fabs +
+- NX M_FREG M_FREG %1111001000eeeeee m_fabs +
+- NX M_FREG M_AM_NONE %1111001000eeeeee m_fabs
+fsabs NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_fsabs +
+- NX M_FREG M_FREG %1111001000eeeeee m_fsabs +
+- NX M_FREG M_AM_NONE %1111001000eeeeee m_fsabs
+fdabs NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_fdabs +
+- NX M_FREG M_FREG %1111001000eeeeee m_fdabs +
+- NX M_FREG M_AM_NONE %1111001000eeeeee m_fdabs
+facos NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_facos +
+- NX M_FREG M_FREG %1111001000eeeeee m_facos +
+- NX M_FREG M_AM_NONE %1111001000eeeeee m_facos
+fadd NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_fadd +
+- NX M_FREG M_FREG %1111001000eeeeee m_fadd
+fsadd NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_fsadd +
+- NX M_FREG M_FREG %1111001000eeeeee m_fsadd
+fdadd NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_fdadd +
+- NX M_FREG M_FREG %1111001000eeeeee m_fdadd
+fasin NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_fasin +
+- NX M_FREG M_FREG %1111001000eeeeee m_fasin +
+- NX M_FREG M_AM_NONE %1111001000eeeeee m_fasin
+fatan NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_fatan +
+- NX M_FREG M_FREG %1111001000eeeeee m_fatan +
+- NX M_FREG M_AM_NONE %1111001000eeeeee m_fatan
+fatanh NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_fatanh +
+- NX M_FREG M_FREG %1111001000eeeeee m_fatanh +
+- NX M_FREG M_AM_NONE %1111001000eeeeee m_fatanh
+
+fbeq NBW C_LABEL M_AM_NONE %111100101s000001 m_cpbr
+fbze
+fbz
+fbge NWL C_LABEL M_AM_NONE %111100101s010011 m_cpbr
+fbgt NWL C_LABEL M_AM_NONE %111100101s010010 m_cpbr
+fbgl NWL C_LABEL M_AM_NONE %111100101s010110 m_cpbr
+fbgle NWL C_LABEL M_AM_NONE %111100101s010111 m_cpbr
+fble NWL C_LABEL M_AM_NONE %111100101s010101 m_cpbr
+fblt NWL C_LABEL M_AM_NONE %111100101s010100 m_cpbr
+fbne NWL C_LABEL M_AM_NONE %111100101s001110 m_cpbr
+fbngt NWL C_LABEL M_AM_NONE %111100101s011101 m_cpbr
+fbnge NWL C_LABEL M_AM_NONE %111100101s011100 m_cpbr
+fbngl NWL C_LABEL M_AM_NONE %111100101s011001 m_cpbr
+fbnle NWL C_LABEL M_AM_NONE %111100101s011010 m_cpbr
+fbnlt NWL C_LABEL M_AM_NONE %111100101s011011 m_cpbr
+fbngle NWL C_LABEL M_AM_NONE %111100101s011000 m_cpbr
+fbnz
+fbogt NWL C_LABEL M_AM_NONE %111100101s000010 m_cpbr
+fbule NWL C_LABEL M_AM_NONE %111100101s001101 m_cpbr
+fboge NWL C_LABEL M_AM_NONE %111100101s000011 m_cpbr
+fbult NWL C_LABEL M_AM_NONE %111100101s001100 m_cpbr
+fbolt NWL C_LABEL M_AM_NONE %111100101s000100 m_cpbr
+fbuge NWL C_LABEL M_AM_NONE %111100101s001011 m_cpbr
+fbole NWL C_LABEL M_AM_NONE %111100101s000101 m_cpbr
+fbugt NWL C_LABEL M_AM_NONE %111100101s001010 m_cpbr
+fbogl NWL C_LABEL M_AM_NONE %111100101s000110 m_cpbr
+fbueq NWL C_LABEL M_AM_NONE %111100101s001001 m_cpbr
+fbor NWL C_LABEL M_AM_NONE %111100101s000111 m_cpbr
+fbun NWL C_LABEL M_AM_NONE %111100101s001000 m_cpbr
+fbt NWL C_LABEL M_AM_NONE %111100101s001111 m_cpbr
+fbra
+fbf NWL C_LABEL M_AM_NONE %111100101s000000 m_cpbr
+fbsf NWL C_LABEL M_AM_NONE %111100101s010000 m_cpbr
+fbst NWL C_LABEL M_AM_NONE %111100101s011111 m_cpbr
+fbseq NWL C_LABEL M_AM_NONE %111100101s010001 m_cpbr
+fbsne NWL C_LABEL M_AM_NONE %111100101s011110 m_cpbr
+
+fcmp NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_fcmp +
+- NX M_FREG M_FREG %1111001000eeeeee m_fcmp
+fcos NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_fcos +
+- NX M_FREG M_FREG %1111001000eeeeee m_fcos +
+- NX M_FREG M_AM_NONE %1111001000eeeeee m_fcos
+fcosh NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_fcosh +
+- NX M_FREG M_FREG %1111001000eeeeee m_fcosh +
+- NX M_FREG M_AM_NONE %1111001000eeeeee m_fcosh
+
+fdbeq N M_DREG C_LABEL %1111001001000001 m_fdbcc
+fdbze
+fdbz
+fdbge N M_DREG C_LABEL %1111001001010011 m_fdbcc
+fdbgt N M_DREG C_LABEL %1111001001010010 m_fdbcc
+fdbgl N M_DREG C_LABEL %1111001001010110 m_fdbcc
+fdbgle N M_DREG C_LABEL %1111001001010111 m_fdbcc
+fdble N M_DREG C_LABEL %1111001001010101 m_fdbcc
+fdblt N M_DREG C_LABEL %1111001001010100 m_fdbcc
+fdbne N M_DREG C_LABEL %1111001001001110 m_fdbcc
+fdbngt N M_DREG C_LABEL %1111001001011101 m_fdbcc
+fdbnge N M_DREG C_LABEL %1111001001011100 m_fdbcc
+fdbngl N M_DREG C_LABEL %1111001001011001 m_fdbcc
+fdbnle N M_DREG C_LABEL %1111001001011010 m_fdbcc
+fdbnlt N M_DREG C_LABEL %1111001001011011 m_fdbcc
+fdbngle N M_DREG C_LABEL %1111001001011000 m_fdbcc
+fdbnz
+fdbogt N M_DREG C_LABEL %1111001001000010 m_fdbcc
+fdbule N M_DREG C_LABEL %1111001001001101 m_fdbcc
+fdboge N M_DREG C_LABEL %1111001001000011 m_fdbcc
+fdbult N M_DREG C_LABEL %1111001001001100 m_fdbcc
+fdbolt N M_DREG C_LABEL %1111001001000100 m_fdbcc
+fdbuge N M_DREG C_LABEL %1111001001001011 m_fdbcc
+fdbole N M_DREG C_LABEL %1111001001000101 m_fdbcc
+fdbugt N M_DREG C_LABEL %1111001001001010 m_fdbcc
+fdbogl N M_DREG C_LABEL %1111001001000110 m_fdbcc
+fdbueq N M_DREG C_LABEL %1111001001001001 m_fdbcc
+fdbor N M_DREG C_LABEL %1111001001000111 m_fdbcc
+fdbun N M_DREG C_LABEL %1111001001001000 m_fdbcc
+fdbt N M_DREG C_LABEL %1111001001001111 m_fdbcc
+fdbra N M_DREG C_LABEL %1111001001000000 m_fdbcc
+fdbf N M_DREG C_LABEL %1111001001000000 m_fdbcc
+fdbsf N M_DREG C_LABEL %1111001001010000 m_fdbcc
+fdbst N M_DREG C_LABEL %1111001001011111 m_fdbcc
+fdbseq N M_DREG C_LABEL %1111001001010001 m_fdbcc
+fdbsne N M_DREG C_LABEL %1111001001011110 m_fdbcc
+
+fdiv NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_fdiv +
+- NX M_FREG M_FREG %1111001000eeeeee m_fdiv +
+- NX M_FREG M_AM_NONE %1111001000eeeeee m_fdiv
+fsdiv NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_fsdiv +
+- NX M_FREG M_FREG %1111001000eeeeee m_fsdiv +
+- NX M_FREG M_AM_NONE %1111001000eeeeee m_fsdiv
+fddiv NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_fddiv +
+- NX M_FREG M_FREG %1111001000eeeeee m_fddiv +
+- NX M_FREG M_AM_NONE %1111001000eeeeee m_fddiv
+fetox NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_fetox +
+- NX M_FREG M_FREG %1111001000eeeeee m_fetox +
+- NX M_FREG M_AM_NONE %1111001000eeeeee m_fetox
+fetoxm1 NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_fetoxm1 +
+- NX M_FREG M_FREG %1111001000eeeeee m_fetoxm1 +
+- NX M_FREG M_AM_NONE %1111001000eeeeee m_fetoxm1
+fgetexp NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_fgetexp +
+- NX M_FREG M_FREG %1111001000eeeeee m_fgetexp +
+- NX M_FREG M_AM_NONE %1111001000eeeeee m_fgetexp
+fgetman NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_fgetman +
+- NX M_FREG M_FREG %1111001000eeeeee m_fgetman +
+- NX M_FREG M_AM_NONE %1111001000eeeeee m_fgetman
+fint NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_fint +
+- NX M_FREG M_FREG %1111001000eeeeee m_fint +
+- NX M_FREG M_AM_NONE %1111001000eeeeee m_fint
+fintrz NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_fintrz +
+- NX M_FREG M_FREG %1111001000eeeeee m_fintrz +
+- NX M_FREG M_AM_NONE %1111001000eeeeee m_fintrz
+flog10 NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_flog10 +
+- NX M_FREG M_FREG %1111001000eeeeee m_flog10 +
+- NX M_FREG M_AM_NONE %1111001000eeeeee m_flog10
+flog2 NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_flog2 +
+- NX M_FREG M_FREG %1111001000eeeeee m_flog2 +
+- NX M_FREG M_AM_NONE %1111001000eeeeee m_flog2
+flogn NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_flogn +
+- NX M_FREG M_FREG %1111001000eeeeee m_flogn +
+- NX M_FREG M_AM_NONE %1111001000eeeeee m_flogn
+flognp1 NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_flognp1 +
+- NX M_FREG M_FREG %1111001000eeeeee m_flognp1 +
+- NX M_FREG M_AM_NONE %1111001000eeeeee m_flognp1
+fmod NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_fmod +
+- NX M_FREG M_FREG %1111001000eeeeee m_fmod +
+- NX M_FREG M_AM_NONE %1111001000eeeeee m_fmod
+fmove NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_fmove +
+- NBWLSQXP M_FREG C_ALL030 %1111001000eeeeee m_fmove +
+- NBWLSQXP M_FREG M_FREG %1111001000eeeeee m_fmove +
+- NL M_FPSCR C_ALL030 %1111001000eeeeee m_fmovescr +
+- NL C_ALL030 M_FPSCR %1111001000eeeeee m_fmovescr +
+fsmove NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_fsmove
+fdmove NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_fdmove
+fmovecr NX M_IMMED M_FREG %1111001000000000 m_fmovecr
+fmovem ! M_AM_NONE M_AM_NONE %1111001000eeeeee m_fmovem
+fmul NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_fmul +
+- NX M_FREG M_FREG %1111001000eeeeee m_fmul
+fsmul NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_fsmul +
+- NX M_FREG M_FREG %1111001000eeeeee m_fsmul
+fdmul NX C_ALL030 M_FREG %1111001000eeeeee m_fdmul +
+- NX M_FREG M_FREG %1111001000eeeeee m_fdmul
+fneg NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_fneg +
+- NX M_FREG M_FREG %1111001000eeeeee m_fneg +
+- NX M_FREG M_AM_NONE %1111001000eeeeee m_fneg
+fsneg NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_fsneg +
+- NX M_FREG M_FREG %1111001000eeeeee m_fsneg +
+- NX M_FREG M_AM_NONE %1111001000eeeeee m_fsneg
+fdneg NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_fdneg +
+- NX M_FREG M_FREG %1111001000eeeeee m_fdneg +
+- NX M_FREG M_AM_NONE %1111001000eeeeee m_fdneg
+fnop N M_AM_NONE M_AM_NONE %1111001010000000 m_fnop
+frem NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_frem +
+- NX M_FREG M_FREG %1111001000eeeeee m_frem
+fscale NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_fscale +
+- NX M_FREG M_FREG %1111001000eeeeee m_fscale
+
+fseq NB C_ALL030 M_AM_NONE %1111001001eeeeee m_fseq
+fsze
+fsz
+fsge NB C_ALL030 M_AM_NONE %1111001001eeeeee m_fsge
+fsgt NB C_ALL030 M_AM_NONE %1111001001eeeeee m_fsgt
+fsgl NB C_ALL030 M_AM_NONE %1111001001eeeeee m_fsgl
+fsgle NB C_ALL030 M_AM_NONE %1111001001eeeeee m_fsgle
+fsle NB C_ALL030 M_AM_NONE %1111001001eeeeee m_fsle
+fslt NB C_ALL030 M_AM_NONE %1111001001eeeeee m_fslt
+fsne NB C_ALL030 M_AM_NONE %1111001001eeeeee m_fsne
+fsngt NB C_ALL030 M_AM_NONE %1111001001eeeeee m_fsngt
+fsnge NB C_ALL030 M_AM_NONE %1111001001eeeeee m_fsnge
+fsngl NB C_ALL030 M_AM_NONE %1111001001eeeeee m_fsngl
+fsnle NB C_ALL030 M_AM_NONE %1111001001eeeeee m_fsnle
+fsnlt NB C_ALL030 M_AM_NONE %1111001001eeeeee m_fsnlt
+fsngle NB C_ALL030 M_AM_NONE %1111001001eeeeee m_fsngle
+fsogt NB C_ALL030 M_AM_NONE %1111001001eeeeee m_fsogt
+fsule NB C_ALL030 M_AM_NONE %1111001001eeeeee m_fsule
+fsoge NB C_ALL030 M_AM_NONE %1111001001eeeeee m_fsoge
+fsult NB C_ALL030 M_AM_NONE %1111001001eeeeee m_fsult
+fsolt NB C_ALL030 M_AM_NONE %1111001001eeeeee m_fsolt
+fsuge NB C_ALL030 M_AM_NONE %1111001001eeeeee m_fsuge
+fsole NB C_ALL030 M_AM_NONE %1111001001eeeeee m_fsole
+fsugt NB C_ALL030 M_AM_NONE %1111001001eeeeee m_fsugt
+fsogl NB C_ALL030 M_AM_NONE %1111001001eeeeee m_fsogl
+fsueq NB C_ALL030 M_AM_NONE %1111001001eeeeee m_fsueq
+fsor NB C_ALL030 M_AM_NONE %1111001001eeeeee m_fsor
+fsun NB C_ALL030 M_AM_NONE %1111001001eeeeee m_fsun
+fst NB C_ALL030 M_AM_NONE %1111001001eeeeee m_fst
+fsf NB C_ALL030 M_AM_NONE %1111001001eeeeee m_fsf
+fssf NB C_ALL030 M_AM_NONE %1111001001eeeeee m_fssf
+fsst NB C_ALL030 M_AM_NONE %1111001001eeeeee m_fsst
+fsseq NB C_ALL030 M_AM_NONE %1111001001eeeeee m_fsseq
+fssne NB C_ALL030 M_AM_NONE %1111001001eeeeee m_fssne
+
+fsgldiv NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_fsgldiv +
+- NX M_FREG M_FREG %1111001000eeeeee m_fsgldiv
+fsglmul NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_fsglmul +
+- NX M_FREG M_FREG %1111001000eeeeee m_fsglmul
+fsin NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_fsin +
+- NX M_FREG M_FREG %1111001000eeeeee m_fsin +
+- NX M_FREG M_AM_NONE %1111001000eeeeee m_fsin
+fsincos NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_fsincos +
+- NX M_FREG M_FREG %1111001000eeeeee m_fsincos
+fsinh NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_fsinh +
+- NX M_FREG M_FREG %1111001000eeeeee m_fsinh +
+- NX M_FREG M_AM_NONE %1111001000eeeeee m_fsinh
+fsqrt NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_fsqrt +
+- NX M_FREG M_FREG %1111001000eeeeee m_fsqrt +
+- NX M_FREG M_AM_NONE %1111001000eeeeee m_fsqrt
+fssqrt NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_fsfsqrt +
+- NX M_FREG M_FREG %1111001000eeeeee m_fsfsqrt +
+- NX M_FREG M_AM_NONE %1111001000eeeeee m_fsfsqrt
+fdsqrt NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_fdfsqrt +
+- NX M_FREG M_FREG %1111001000eeeeee m_fdfsqrt +
+- NX M_FREG M_AM_NONE %1111001000eeeeee m_fdfsqrt
+fsub NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_fsub +
+- NX M_FREG M_FREG %1111001000eeeeee m_fsub
+fssub NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_fsub +
+- NX M_FREG M_FREG %1111001000eeeeee m_fsub
+fdsub NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_fdsub +
+- NX M_FREG M_FREG %1111001000eeeeee m_fdsub
+ftan NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_ftan +
+- NX M_FREG M_FREG %1111001000eeeeee m_ftan +
+- NX M_FREG M_AM_NONE %1111001000eeeeee m_ftan
+ftanh NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_ftanh +
+- NX M_FREG M_FREG %1111001000eeeeee m_ftanh +
+- NX M_FREG M_AM_NONE %1111001000eeeeee m_ftanh
+ftentox NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_ftentox +
+- NX M_FREG M_FREG %1111001000eeeeee m_ftentox +
+- NX M_FREG M_AM_NONE %1111001000eeeeee m_ftentox
+ftst NBWLSQXP C_ALL030 M_AM_NONE %1111001000eeeeee m_ftst +
+- X M_FREG M_AM_NONE %1111001000eeeeee m_ftst
+ftwotox NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_ftwotox +
+- NX M_FREG M_FREG %1111001000eeeeee m_ftwotox +
+- NX M_FREG M_AM_NONE %1111001000eeeeee m_ftwotox
+
+ftrapeq WL M_IMMED M_AM_NONE %1111001001111e10 m_ftrapeq +
+- N M_AM_NONE M_AM_NONE %1111001001111eee m_ftrapeqn
+ftrapze
+ftrapz
+ftrapge WL M_IMMED M_AM_NONE %111100100111101e m_ftrapge +
+- N M_AM_NONE M_AM_NONE %1111001001111100 m_ftrapgen
+ftrapgt WL M_IMMED M_AM_NONE %111100100111101e m_ftrapgt +
+- N M_AM_NONE M_AM_NONE %1111001001111100 m_ftrapgtn
+ftrapgl WL M_IMMED M_AM_NONE %111100100111101e m_ftrapgl +
+- N M_AM_NONE M_AM_NONE %1111001001111100 m_ftrapgln
+ftrapgle WL M_IMMED M_AM_NONE %111100100111101e m_ftrapgle +
+- N M_AM_NONE M_AM_NONE %1111001001111100 m_ftrapglen
+ftraple WL M_IMMED M_AM_NONE %111100100111101e m_ftraple +
+- N M_AM_NONE M_AM_NONE %1111001001111100 m_ftraplen
+ftraplt WL M_IMMED M_AM_NONE %111100100111101e m_ftraplt +
+- N M_AM_NONE M_AM_NONE %1111001001111100 m_ftrapltn
+ftrapne WL M_IMMED M_AM_NONE %111100100111101e m_ftrapne +
+- N M_AM_NONE M_AM_NONE %1111001001111100 m_ftrapnen
+ftrapngt WL M_IMMED M_AM_NONE %111100100111101e m_ftrapngt +
+- N M_AM_NONE M_AM_NONE %1111001001111100 m_ftrapngtn
+ftrapnge WL M_IMMED M_AM_NONE %111100100111101e m_ftrapnge +
+- N M_AM_NONE M_AM_NONE %1111001001111100 m_ftrapngen
+ftrapngl WL M_IMMED M_AM_NONE %111100100111101e m_ftrapngl +
+- N M_AM_NONE M_AM_NONE %1111001001111100 m_ftrapngln
+ftrapnle WL M_IMMED M_AM_NONE %111100100111101e m_ftrapnle +
+- N M_AM_NONE M_AM_NONE %1111001001111100 m_ftrapnlen
+ftrapnlt WL M_IMMED M_AM_NONE %111100100111101e m_ftrapnlt +
+- N M_AM_NONE M_AM_NONE %1111001001111100 m_ftrapnltn
+ftrapngle WL M_IMMED M_AM_NONE %111100100111101e m_ftrapngle +
+- N M_AM_NONE M_AM_NONE %1111001001111100 m_ftrapnglen
+ftrapogt WL M_IMMED M_AM_NONE %111100100111101e m_ftrapogt +
+- N M_AM_NONE M_AM_NONE %1111001001111100 m_ftrapogtn
+ftrapule WL M_IMMED M_AM_NONE %111100100111101e m_ftrapule +
+- N M_AM_NONE M_AM_NONE %1111001001111100 m_ftrapulen
+ftrapoge WL M_IMMED M_AM_NONE %111100100111101e m_ftrapoge +
+- N M_AM_NONE M_AM_NONE %1111001001111100 m_ftrapogen
+ftrapult WL M_IMMED M_AM_NONE %111100100111101e m_ftrapult +
+- N M_AM_NONE M_AM_NONE %1111001001111100 m_ftrapultn
+ftrapolt WL M_IMMED M_AM_NONE %111100100111101e m_ftrapolt +
+- N M_AM_NONE M_AM_NONE %1111001001111100 m_ftrapoltn
+ftrapuge WL M_IMMED M_AM_NONE %111100100111101e m_ftrapuge +
+- N M_AM_NONE M_AM_NONE %1111001001111100 m_ftrapugen
+ftrapole WL M_IMMED M_AM_NONE %111100100111101e m_ftrapole +
+- N M_AM_NONE M_AM_NONE %1111001001111100 m_ftrapolen
+ftrapugt WL M_IMMED M_AM_NONE %111100100111101e m_ftrapugt +
+- N M_AM_NONE M_AM_NONE %1111001001111100 m_ftrapugtn
+ftrapogl WL M_IMMED M_AM_NONE %111100100111101e m_ftrapogl +
+- N M_AM_NONE M_AM_NONE %1111001001111100 m_ftrapogln
+ftrapueq WL M_IMMED M_AM_NONE %111100100111101e m_ftrapueq +
+- N M_AM_NONE M_AM_NONE %1111001001111100 m_ftrapueqn
+ftrapor WL M_IMMED M_AM_NONE %111100100111101e m_ftrapor +
+- N M_AM_NONE M_AM_NONE %1111001001111100 m_ftraporn
+ftrapun WL M_IMMED M_AM_NONE %111100100111101e m_ftrapun +
+- N M_AM_NONE M_AM_NONE %1111001001111100 m_ftrapunn
+ftrapt WL M_IMMED M_AM_NONE %111100100111101e m_ftrapt +
+- N M_AM_NONE M_AM_NONE %1111001001111100 m_ftraptn
+ftrapf WL M_IMMED M_AM_NONE %111100100111101e m_ftrapf +
+- N M_AM_NONE M_AM_NONE %1111001001111100 m_ftrapfn
+ftrapsf WL M_IMMED M_AM_NONE %111100100111101e m_ftrapsf +
+- N M_AM_NONE M_AM_NONE %1111001001111100 m_ftrapsfn
+ftrapst WL M_IMMED M_AM_NONE %111100100111101e m_ftrapst +
+- N M_AM_NONE M_AM_NONE %1111001001111100 m_ftrapstn
+ftrapseq WL M_IMMED M_AM_NONE %111100100111101e m_ftrapseq +
+- N M_AM_NONE M_AM_NONE %1111001001111100 m_ftrapseqn
+ftrapsne WL M_IMMED M_AM_NONE %111100100111101e m_ftrapsne +
+- N M_AM_NONE M_AM_NONE %1111001001111100 m_ftrapsnen
+
+
+frestore N C_DATA030 M_AM_NONE %1111001101eeeeee m_cprest
+fsave N C_DATA030 M_AM_NONE %1111001100eeeeee m_cprest
illegal N M_AM_NONE M_AM_NONE %0100101011111100 m_self
-jmp N C_CTRL M_AM_NONE %0100111011eee000 m_ea
+jmp N C_CTRL M_AM_NONE %0100111011eee000 m_ea +
+- N C_CTRL030 M_AM_NONE %0100111011eee000 m_ea030
jsr N C_CTRL M_AM_NONE %0100111010eee000 m_ea
-lea NL C_CTRL M_AREG %0100rrr111eR1000 m_ea
+lea NL C_CTRL M_AREG %0100rrr111eR1000 m_lea
-link N M_AREG M_IMMED %0100111001010rrr m_link
+link NWL M_AREG M_IMMED %0100111001010rrr m_link
lsl NBWL M_DREG M_DREG %1110rrr1ss101rrr m_shr +
- NBWL M_IMMED M_DREG %1110ccc1ss001rrr m_shi +
- NW M_AM_SR C_ALTDATA %0100000011ddd001 m_ea +
- NW C_DATA M_AM_CCR %0100010011sss000 m_ea +
- NL M_AM_USP M_AREG %0100111001101rrr m_usp +
-- NL M_AREG M_AM_USP %0100111001100rrr m_usp
+- NL M_AREG M_AM_USP %0100111001100rrr m_usp +
+- NBWL C_ALL030 C_ALTDATA %00ssddddddssssss m_move30 +
+- NBWL C_ALL030 C_ALL030 %00ssddddddssssss m_move30 +
+- NW M_AM_CCR C_DATA030 %0100001011sss000 m_ea030
movea NWL C_ALL M_AREG %00ssddd001ssssss m_move
+movec NL M_DREG+M_AREG C_CREG %0100111001111011 m_movec +
+- NL C_CREG M_DREG+M_AREG %0100111001111010 m_movec
+
+moves NBWL M_DREG+M_AREG C_MOVES %00001110sseeeeee m_moves +
+- NBWL C_MOVES M_DREG+M_AREG %00001110sseeeeee m_moves
+
+move16 N APOSTINC APOSTINC %1111011000100rrr m_move16a +
+- N AIND+APOSTINC+ABSL AIND+APOSTINC+ABSL %11110110000ooorrr m_move16b
+
movem ! M_AM_NONE M_AM_NONE %01001d001seeeeee m_movem
movep NWL M_DREG M_AIND|M_ADISP %0000rrr11s001aaa m_movep +
moveq NL M_IMMED M_DREG %0111rrr0dddddddd m_moveq
-muls NW C_DATA M_DREG %1100rrr111eR1000 m_ea
-mulu NW C_DATA M_DREG %1100rrr011eR1000 m_ea
+muls NW C_DATA M_DREG %1100rrr111eR1000 m_ea +
+- L C_DATA030 M_DREG %0100110000eeeeee m_muls
+mulu NW C_DATA M_DREG %1100rrr011eR1000 m_ea +
+- L C_DATA030 M_DREG %0100110000eeeeee m_mulu
+
nbcd NB C_ALTDATA M_AM_NONE %0100100000eee000 m_ea
neg NBWL C_ALTDATA M_AM_NONE %01000100sseeeS00 m_ea
negx NBWL C_ALTDATA M_AM_NONE %01000000sseeeS00 m_ea
- NB M_IMMED M_AM_CCR %0000000000111100 m_imm8 +
- NW M_IMMED M_AM_SR %0000000001111100 m_imm
+pack ! M_AM_NONE M_AM_NONE %1000rrr10100mrrr m_pack
+
+pbbs NWL C_LABEL M_AM_NONE %111100001s000000 m_cpbr
+pbls NWL C_LABEL M_AM_NONE %111100001s000010 m_cpbr
+pbss NWL C_LABEL M_AM_NONE %111100001s000100 m_cpbr
+pbas NWL C_LABEL M_AM_NONE %111100001s000110 m_cpbr
+pbws NWL C_LABEL M_AM_NONE %111100001s001000 m_cpbr
+pbis NWL C_LABEL M_AM_NONE %111100001s001010 m_cpbr
+pbgs NWL C_LABEL M_AM_NONE %111100001s001100 m_cpbr
+pbcs NWL C_LABEL M_AM_NONE %111100001s001110 m_cpbr
+pbbc NWL C_LABEL M_AM_NONE %111100001s000001 m_cpbr
+pblc NWL C_LABEL M_AM_NONE %111100001s000011 m_cpbr
+pbsc NWL C_LABEL M_AM_NONE %111100001s000101 m_cpbr
+pbac NWL C_LABEL M_AM_NONE %111100001s000111 m_cpbr
+pbwc NWL C_LABEL M_AM_NONE %111100001s001001 m_cpbr
+pbic NWL C_LABEL M_AM_NONE %111100001s001011 m_cpbr
+pbgc NWL C_LABEL M_AM_NONE %111100001s001101 m_cpbr
+pbcc NWL C_LABEL M_AM_NONE %111100001s001111 m_cpbr
+
+pdbbs NWL M_DREG C_LABEL %1111000001001ccc m_cpdbr
+pdbls NWL M_DREG C_LABEL %1111000001001ccc m_cpdbr
+pdbss NWL M_DREG C_LABEL %1111000001001ccc m_cpdbr
+pdbas NWL M_DREG C_LABEL %1111000001001ccc m_cpdbr
+pdbws NWL M_DREG C_LABEL %1111000001001ccc m_cpdbr
+pdbis NWL M_DREG C_LABEL %1111000001001ccc m_cpdbr
+pdbgs NWL M_DREG C_LABEL %1111000001001ccc m_cpdbr
+pdbcs NWL M_DREG C_LABEL %1111000001001ccc m_cpdbr
+pdbbc NWL M_DREG C_LABEL %1111000001001ccc m_cpdbr
+pdblc NWL M_DREG C_LABEL %1111000001001ccc m_cpdbr
+pdbsc NWL M_DREG C_LABEL %1111000001001ccc m_cpdbr
+pdbac NWL M_DREG C_LABEL %1111000001001ccc m_cpdbr
+pdbwc NWL M_DREG C_LABEL %1111000001001ccc m_cpdbr
+pdbic NWL M_DREG C_LABEL %1111000001001ccc m_cpdbr
+pdbgc NWL M_DREG C_LABEL %1111000001001ccc m_cpdbr
+pdbcc NWL M_DREG C_LABEL %1111000001001ccc m_cpdbr
+
+pflusha N M_AM_NONE M_AM_NONE %1111000000000000 m_pflusha
+pflush N M_CREG+M_DREG+M_IMMED M_IMMED %1111000000eeeeee m_pflush
+pflushr N C_ALL030 M_AM_NONE %1111000000eeeeee m_pflushr
+
+ploadr N M_FC C_ALL030 %1111000000eeeeee m_pload
+ploadw N M_FC C_ALL030 %1111000000eeeeee m_pload
+
+pmove NWLD M_MRN C_ALL030 %1111000000eeeeee m_pmove +
+- NWLD C_ALL030 M_MRN %1111000000eeeeee m_pmove
+pmovefd NWLD C_ALL030 M_MRN %1111000000eeeeee m_pmovefd
+
+prestore N C_ALL030 M_AM_NONE %1111000101eeeeee m_ea
+psave N C_ALL030 M_AM_NONE %1111000100eeeeee m_ea
+
+ptestr N M_FC M_IMMED %1111000000eeeeee m_ptest
+ptestw N M_FC M_IMMED %1111000000eeeeee m_ptest
+
+ptrapbs WL M_IMMED M_AM_NONE %111100000111101o m_ptrapbs +
+- N M_AM_NONE M_AM_NONE %1111000001111100 m_ptrapbsn
+ptrapls WL M_IMMED M_AM_NONE %111100000111101o m_ptrapls +
+- N M_AM_NONE M_AM_NONE %1111000001111100 m_ptraplsn
+ptrapss WL M_IMMED M_AM_NONE %111100000111101o m_ptrapss +
+- N M_AM_NONE M_AM_NONE %1111000001111100 m_ptrapssn
+ptrapas WL M_IMMED M_AM_NONE %111100000111101o m_ptrapas +
+- N M_AM_NONE M_AM_NONE %1111000001111100 m_ptrapasn
+ptrapws WL M_IMMED M_AM_NONE %111100000111101o m_ptrapws +
+- N M_AM_NONE M_AM_NONE %1111000001111100 m_ptrapwsn
+ptrapis WL M_IMMED M_AM_NONE %111100000111101o m_ptrapis +
+- N M_AM_NONE M_AM_NONE %1111000001111100 m_ptrapisn
+ptrapgs WL M_IMMED M_AM_NONE %111100000111101o m_ptrapgs +
+- N M_AM_NONE M_AM_NONE %1111000001111100 m_ptrapgsn
+ptrapcs WL M_IMMED M_AM_NONE %111100000111101o m_ptrapcs +
+- N M_AM_NONE M_AM_NONE %1111000001111100 m_ptrapcsn
+ptrapbc WL M_IMMED M_AM_NONE %111100000111101o m_ptrapbc +
+- N M_AM_NONE M_AM_NONE %1111000001111100 m_ptrapbcn
+ptraplc WL M_IMMED M_AM_NONE %111100000111101o m_ptraplc +
+- N M_AM_NONE M_AM_NONE %1111000001111100 m_ptraplcn
+ptrapsc WL M_IMMED M_AM_NONE %111100000111101o m_ptrapsc +
+- N M_AM_NONE M_AM_NONE %1111000001111100 m_ptrapscn
+ptrapac WL M_IMMED M_AM_NONE %111100000111101o m_ptrapac +
+- N M_AM_NONE M_AM_NONE %1111000001111100 m_ptrapacn
+ptrapwc WL M_IMMED M_AM_NONE %111100000111101o m_ptrapwc +
+- N M_AM_NONE M_AM_NONE %1111000001111100 m_ptrapwcn
+ptrapic WL M_IMMED M_AM_NONE %111100000111101o m_ptrapic +
+- N M_AM_NONE M_AM_NONE %1111000001111100 m_ptrapicn
+ptrapgc WL M_IMMED M_AM_NONE %111100000111101o m_ptrapgc +
+- N M_AM_NONE M_AM_NONE %1111000001111100 m_ptrapgcn
+ptrapcc WL M_IMMED M_AM_NONE %111100000111101o m_ptrapcc +
+- N M_AM_NONE M_AM_NONE %1111000001111100 m_ptrapccn
+
pea NL C_CTRL M_AM_NONE %0100100001eee000 m_ea
reset N M_AM_NONE M_AM_NONE 0x4e70 m_self
- NBWL C_ALTMEM M_AM_NONE %1110010011eee000 m_ea +
- NBWL M_DREG M_AM_NONE %11100010ss010rrS m_reg
+rtd N M_IMMED M_AM_NONE %0100111001110100 m_rtd
rte N M_AM_NONE M_AM_NONE 0x4e73 m_self
+rtm N M_DREG+M_AREG M_AM_NONE %000001101100drrr m_rtm
rtr N M_AM_NONE M_AM_NONE 0x4e77 m_self
rts N M_AM_NONE M_AM_NONE 0x4e75 m_self
swap NW M_DREG M_AM_NONE %0100100001000rrr m_reg
tas NB C_ALTDATA M_AM_NONE %0100101011eee000 m_ea
trap N M_IMMED M_AM_NONE %010011100100vvvv m_trap
+trapcc NWL M_IMMED M_AM_NONE %0101010011111ooo m_trapcc +
+- NWL M_AM_NONE M_AM_NONE %0101010011111100 m_self
+trapcs NWL M_IMMED M_AM_NONE %0101010111111ooo m_trapcc +
+- NWL M_AM_NONE M_AM_NONE %0101010111111100 m_self
+traplo
+trapeq NWL M_IMMED M_AM_NONE %0101011111111ooo m_trapcc +
+- NWL M_AM_NONE M_AM_NONE %0101011111111100 m_self
+trapze
+trapf NWL M_IMMED M_AM_NONE %0101000111111ooo m_trapcc +
+- NWL M_AM_NONE M_AM_NONE %0101000111111100 m_self
+trapge NWL M_IMMED M_AM_NONE %0101110011111ooo m_trapcc +
+- NWL M_AM_NONE M_AM_NONE %0101110011111100 m_self
+trapgt NWL M_IMMED M_AM_NONE %0101111011111ooo m_trapcc +
+- NWL M_AM_NONE M_AM_NONE %0101111011111100 m_self
+traphi NWL M_IMMED M_AM_NONE %0101001011111ooo m_trapcc +
+- NWL M_AM_NONE M_AM_NONE %0101001011111100 m_self
+traple NWL M_IMMED M_AM_NONE %0101111111111ooo m_trapcc +
+- NWL M_AM_NONE M_AM_NONE %0101111111111100 m_self
+trapls NWL M_IMMED M_AM_NONE %0101001111111ooo m_trapcc +
+- NWL M_AM_NONE M_AM_NONE %0101001111111100 m_self
+traplt NWL M_IMMED M_AM_NONE %0101110111111ooo m_trapcc +
+- NWL M_AM_NONE M_AM_NONE %0101110111111100 m_self
+trapmi NWL M_IMMED M_AM_NONE %0101101111111ooo m_trapcc +
+- NWL M_AM_NONE M_AM_NONE %0101101111111100 m_self
+trapne NWL M_IMMED M_AM_NONE %0101011011111ooo m_trapcc +
+- NWL M_AM_NONE M_AM_NONE %0101011011111100 m_self
+trapnz
+trappl NWL M_IMMED M_AM_NONE %0101101011111ooo m_trapcc +
+- NWL M_AM_NONE M_AM_NONE %0101101011111100 m_self
+trapt NWL M_IMMED M_AM_NONE %0101000011111ooo m_trapcc +
+- NWL M_AM_NONE M_AM_NONE %0101000011111100 m_self
+trapvc NWL M_IMMED M_AM_NONE %0101100011111ooo m_trapcc +
+- NWL M_AM_NONE M_AM_NONE %0101100011111100 m_self
+trapvs NWL M_IMMED M_AM_NONE %0101100111111ooo m_trapcc +
+- NWL M_AM_NONE M_AM_NONE %0101100111111100 m_self
trapv N M_AM_NONE M_AM_NONE 0x4e76 m_self
-tst NBWL C_ALTDATA M_AM_NONE %01001010sseeeS00 m_ea
+tst NBWL C_ALTDATA M_AM_NONE %01001010sseeeS00 m_ea +
+- NBWL C_ALL030 M_AM_NONE %01001010sseeeS00 m_ea030
unlk N M_AREG M_AM_NONE %0100111001011rrr m_reg
+unpack ! M_AM_NONE M_AM_NONE %1000rrr11000mrrr m_pack
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
+ <PreBuildEvent>
+ <Command>cd $(SolutionDir)..\
+call maketabs.bat</Command>
+ </PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
//
// RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
// AMODE.C - Addressing Modes
-// Copyright (C) 199x Landon Dyer, 2017 Reboot and Friends
+// Copyright (C) 199x Landon Dyer, 2011 Reboot and Friends
// RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
// Source utilised with the kind permission of Landon Dyer
//
#include "token.h"
#include "expr.h"
#include "rmac.h"
+#include "procln.h"
+#include "sect.h"
#define DEF_KW
#include "kwtab.h"
#define DEF_MN
#include "mntab.h"
+extern int activecpu;
+extern char unsupport[];
+
// Address-mode information
-int nmodes; // Number of addr'ing modes found
-int am0; // Addressing mode
-int a0reg; // Register
-TOKEN a0expr[EXPRSIZE]; // Expression
-VALUE a0exval; // Expression's value
-WORD a0exattr; // Expression's attribute
-int a0ixreg; // Index register
-int a0ixsiz; // Index register size (and scale)
-TOKEN a0oexpr[EXPRSIZE]; // Outer displacement expression
-VALUE a0oexval; // Outer displacement value
-WORD a0oexattr; // Outer displacement attribute
-SYM * a0esym; // External symbol involved in expr
-
-int am1; // Addressing mode
-int a1reg; // Register
-TOKEN a1expr[EXPRSIZE]; // Expression
-VALUE a1exval; // Expression's value
-WORD a1exattr; // Expression's attribute
-int a1ixreg; // Index register
-int a1ixsiz; // Index register size (and scale)
-TOKEN a1oexpr[EXPRSIZE]; // Outer displacement expression
-VALUE a1oexval; // Outer displacement value
-WORD a1oexattr; // Outer displacement attribute
-SYM * a1esym; // External symbol involved in expr
+int nmodes; // Number of addr'ing modes found
+int am0; // Addressing mode
+int a0reg; // Register
+TOKEN a0expr[EXPRSIZE]; // Expression
+VALUE a0exval; // Expression's value
+WORD a0exattr; // Expression's attribute
+int a0ixreg; // Index register
+int a0ixsiz; // Index register size (and scale)
+TOKEN a0oexpr[EXPRSIZE]; // Outer displacement expression
+VALUE a0oexval; // Outer displacement value
+WORD a0oexattr; // Outer displacement attribute
+SYM * a0esym; // External symbol involved in expr
+TOKEN a0bexpr[EXPRSIZE]; // Base displacement expression
+VALUE a0bexval; // Base displacement value
+WORD a0bexattr; // Base displacement attribute
+WORD a0bsize; // Base displacement size
+WORD a0extension; // 020+ extension address word
+WORD am0_030; // ea bits for 020+ addressing modes
+
+int am1; // Addressing mode
+int a1reg; // Register
+TOKEN a1expr[EXPRSIZE]; // Expression
+VALUE a1exval; // Expression's value
+WORD a1exattr; // Expression's attribute
+int a1ixreg; // Index register
+int a1ixsiz; // Index register size (and scale)
+TOKEN a1oexpr[EXPRSIZE]; // Outer displacement expression
+VALUE a1oexval; // Outer displacement value
+WORD a1oexattr; // Outer displacement attribute
+SYM * a1esym; // External symbol involved in expr
+TOKEN a1bexpr[EXPRSIZE]; // Base displacement expression
+VALUE a1bexval; // Base displacement value
+WORD a1bexattr; // Base displacement attribute
+WORD a1bsize; // Base displacement size
+WORD a1extension; // 020+ extension address word
+WORD am1_030; // ea bits for 020+ addressing modes
+int a2reg; // Register for div.l (68020+)
+WORD mulmode; // to distinguish between 32 and 64 bit multiplications (68020+)
//
// Parse addressing mode
//
int amode(int acount)
{
- // Initialize global return values
- nmodes = a0reg = a1reg = 0;
- am0 = am1 = AM_NONE;
- a0expr[0] = a0oexpr[0] = a1expr[0] = a1oexpr[0] = ENDEXPR;
- a0exattr = a0oexattr = a1exattr = a1oexattr = 0;
- a0esym = a1esym = (SYM *)NULL;
-
- // If at EOL, then no addr modes at all
- if (*tok == EOL)
- return 0;
-
- // Parse first addressing mode
- #define AnOK a0ok
- #define AMn am0
- #define AnREG a0reg
- #define AnIXREG a0ixreg
- #define AnIXSIZ a0ixsiz
- #define AnEXPR a0expr
- #define AnEXVAL a0exval
- #define AnEXATTR a0exattr
- #define AnOEXPR a0oexpr
- #define AnOEXVAL a0oexval
- #define AnOEXATTR a0oexattr
- #define AnESYM a0esym
- #define AMn_IX0 am0_ix0
- #define AMn_IXN am0_ixn
- #define CHK_FOR_DISPn CheckForDisp0
- #include "parmode.h"
-
- // If caller wants only one mode, return just one (ignore comma);
- // If there is no second addressing mode (no comma), then return just one anyway.
- nmodes = 1;
-
- if (acount == 0 || *tok != ',')
- return 1;
-
- // Eat the comma
- tok++;
-
- // Parse second addressing mode
- #define AnOK a1ok
- #define AMn am1
- #define AnREG a1reg
- #define AnIXREG a1ixreg
- #define AnIXSIZ a1ixsiz
- #define AnEXPR a1expr
- #define AnEXVAL a1exval
- #define AnEXATTR a1exattr
- #define AnOEXPR a1oexpr
- #define AnOEXVAL a1oexval
- #define AnOEXATTR a1oexattr
- #define AnESYM a1esym
- #define AMn_IX0 am1_ix0
- #define AMn_IXN am1_ixn
- #define CHK_FOR_DISPn CheckForDisp1
- #include "parmode.h"
-
- nmodes = 2;
- return 2;
-
- // Error messages:
- badmode:
- return error("addressing mode syntax");
-
- unmode:
- return error("unimplemented addressing mode");
+ // Initialize global return values
+ nmodes = a0reg = a1reg = 0;
+ am0 = am1 = AM_NONE;
+ a0expr[0] = a0oexpr[0] = a1expr[0] = a1oexpr[0] = ENDEXPR;
+ a0exattr = a0oexattr = a1exattr = a1oexattr = 0;
+ a0esym = a1esym = (SYM *)NULL;
+ a0bexpr[0]=a1bexpr[0]= ENDEXPR;
+ a0bexval=a0bsize=a0extension=a1bexval=a1bsize=a1extension=0;
+ am0_030=am1_030=0;
+ bfparam1=bfparam2=0;
+ bf0expr[0]=ENDEXPR;
+ bf0exattr=0;
+ bf0esym= (SYM *)NULL;
+
+ // If at EOL, then no addr modes at all
+ if (*tok == EOL)
+ return 0;
+
+ // Parse first addressing mode
+ #define AnOK a0ok
+ #define AMn am0
+ #define AnREG a0reg
+ #define AnIXREG a0ixreg
+ #define AnIXSIZ a0ixsiz
+ #define AnEXPR a0expr
+ #define AnEXVAL a0exval
+ #define AnEXATTR a0exattr
+ #define AnOEXPR a0oexpr
+ #define AnOEXVAL a0oexval
+ #define AnOEXATTR a0oexattr
+ #define AnESYM a0esym
+ #define AMn_IX0 am0_ix0
+ #define AMn_IXN am0_ixn
+ #define CHK_FOR_DISPn CheckForDisp0
+ #define AnBEXPR a0bexpr
+ #define AnBEXVAL a0bexval
+ #define AnBEXATTR a0bexattr
+ #define AnBZISE a0bsize
+ #define AnEXTEN a0extension
+ #define AMn_030 am0_030
+ #define IS_SUPPRESSEDn IS_SUPPRESSED0
+ #define CHECKODn CHECKOD0
+ #include "parmode.h"
+
+ // If caller wants only one mode, return just one (ignore comma);
+ // If there is no second addressing mode (no comma), then return just one anyway.
+ nmodes = 1;
+
+ if (*tok == '{')
+ if (check030bf()==ERROR) // it's a bitfield instruction - check the parameters inside the {} block for validity
+ return ERROR;
+
+ if (acount == 0 || *tok != ',')
+ return 1;
+
+ // Eat the comma
+ tok++;
+
+ // Parse second addressing mode
+ #define AnOK a1ok
+ #define AMn am1
+ #define AnREG a1reg
+ #define AnIXREG a1ixreg
+ #define AnIXSIZ a1ixsiz
+ #define AnEXPR a1expr
+ #define AnEXVAL a1exval
+ #define AnEXATTR a1exattr
+ #define AnOEXPR a1oexpr
+ #define AnOEXVAL a1oexval
+ #define AnOEXATTR a1oexattr
+ #define AnESYM a1esym
+ #define AMn_IX0 am1_ix0
+ #define AMn_IXN am1_ixn
+ #define CHK_FOR_DISPn CheckForDisp1
+ #define AnBEXPR a1bexpr
+ #define AnBEXVAL a1bexval
+ #define AnBEXATTR a1bexattr
+ #define AnBZISE a1bsize
+ #define AnEXTEN a1extension
+ #define AMn_030 am1_030
+ #define IS_SUPPRESSEDn IS_SUPPRESSED1
+ #define CHECKODn CHECKOD1
+ #include "parmode.h"
+
+ if (*tok == '{')
+ if (check030bf()==ERROR) // it's a bitfield instruction - check the parameters inside the {} block for validity
+ return ERROR;
+
+ // At this point, it is legal for 020+ to have a ':'. For example divu.l d0,d2:d3
+ if (*tok == ':')
+ {
+ if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
+ return error(unsupport);
+ // TODO: protect this from combinations like Dx:FPx etc :)
+ tok++; //eat the colon
+ if (*tok >= KW_D0 && *tok <= KW_D7)
+ {
+ a2reg = (*tok - KW_D0);
+ mulmode=1<<10;
+ }
+ else if (*tok >= KW_FP0&&*tok <= KW_FP7)
+ {
+ a2reg = (*tok - KW_FP0);
+ mulmode=1<<10;
+ }
+ else
+ return error("a data or FPU register must follow a :");
+ *tok++;
+ }
+ else
+ {
+ //If no ':' is present then maybe we have something like divs.l d0,d1 which sould translate to divs.l d0,d1:d1
+ a2reg = a1reg;
+ mulmode=0;
+ }
+
+ nmodes = 2;
+ return 2;
+
+ // Error messages:
+ badmode:
+ return error("addressing mode syntax");
+
+ //unmode:
+ //return error("unimplemented addressing mode");
}
//
int reglist(WORD * a_rmask)
{
- static WORD msktab[] = {
- 0x0001, 0x0002, 0x0004, 0x0008,
- 0x0010, 0x0020, 0x0040, 0x0080,
- 0x0100, 0x0200, 0x0400, 0x0800,
- 0x1000, 0x2000, 0x4000, 0x8000
- };
+ static WORD msktab[] = {
+ 0x0001, 0x0002, 0x0004, 0x0008,
+ 0x0010, 0x0020, 0x0040, 0x0080,
+ 0x0100, 0x0200, 0x0400, 0x0800,
+ 0x1000, 0x2000, 0x4000, 0x8000
+ };
+
+ WORD rmask = 0;
+ int r, cnt;
+
+ for(;;)
+ {
+ if (*tok >= KW_D0 && *tok <= KW_A7)
+ r = *tok++ & 15;
+ else
+ break;
+
+ if (*tok == '-')
+ {
+ tok++;
+
+ if (*tok >= KW_D0 && *tok <= KW_A7)
+ cnt = *tok++ & 15;
+ else
+ return error("register list syntax");
+
+ if (cnt < r)
+ return error("register list order");
+
+ cnt -= r;
+ }
+ else
+ cnt = 0;
+
+ while (cnt-- >= 0)
+ rmask |= msktab[r++];
+
+ if (*tok != '/')
+ break;
+
+ tok++;
+ }
+
+ *a_rmask = rmask;
+
+ return OK;
+}
+
+//
+// Parse FPU register list
+//
+int fpu_reglist_left(WORD * a_rmask)
+{
+ static WORD msktab_minus[] = {
+ 0x0080, 0x0040, 0x0020, 0x0010,
+ 0x0008, 0x0004, 0x0002, 0x0001
+ };
+
+ WORD rmask = 0;
+ int r, cnt;
+
+ for(;;)
+ {
+ if (*tok >= KW_FP0 && *tok <= KW_FP7)
+ r = *tok++ & 7;
+ else
+ break;
+
+ if (*tok == '-')
+ {
+ tok++;
+
+ if (*tok >= KW_FP0 && *tok <= KW_FP7)
+ cnt = *tok++ & 7;
+ else
+ return error("register list syntax");
+
+ if (cnt < r)
+ return error("register list order");
+
+ cnt -= r;
+ }
+ else
+ cnt = 0;
+
+ while (cnt-- >= 0)
+ rmask |= msktab_minus[r++];
+
+ if (*tok != '/')
+ break;
+
+ tok++;
+ }
+
+ *a_rmask = rmask;
+
+ return OK;
+}
+int fpu_reglist_right(WORD * a_rmask)
+{
+ static WORD msktab_plus[] = {
+ 0x0001, 0x0002, 0x0004, 0x0008,
+ 0x0010, 0x0020, 0x0040, 0x0080
+ };
- WORD rmask = 0;
- int r, cnt;
+ WORD rmask = 0;
+ int r, cnt;
- for(;;)
- {
- if (*tok >= KW_D0 && *tok <= KW_A7)
- r = *tok++ & 15;
- else
- break;
+ for(;;)
+ {
+ if (*tok >= KW_FP0 && *tok <= KW_FP7)
+ r = *tok++ & 7;
+ else
+ break;
- if (*tok == '-')
- {
- tok++;
+ if (*tok == '-')
+ {
+ tok++;
- if (*tok >= KW_D0 && *tok <= KW_A7)
- cnt = *tok++ & 15;
- else
- return error("register list syntax");
+ if (*tok >= KW_FP0 && *tok <= KW_FP7)
+ cnt = *tok++ & 7;
+ else
+ return error("register list syntax");
- if (cnt < r)
- return error("register list order");
+ if (cnt < r)
+ return error("register list order");
- cnt -= r;
- }
- else
- cnt = 0;
+ cnt -= r;
+ }
+ else
+ cnt = 0;
- while (cnt-- >= 0)
- rmask |= msktab[r++];
+ while (cnt-- >= 0)
+ rmask |= msktab_plus[r++];
- if (*tok != '/')
- break;
+ if (*tok != '/')
+ break;
- tok++;
- }
+ tok++;
+ }
- *a_rmask = rmask;
+ *a_rmask = rmask;
- return OK;
+ return OK;
}
+//
+// Check for bitfield instructions extra params
+// These are 020+ instructions and have the following syntax:
+// bfxxx <ea>{param1,param2}
+// param1/2 are either data registers or immediate values
+//
+
+int check030bf(void)
+{
+ WARNING (Add more strict checks as well as checks for non defined (yet) labels)
+
+ if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
+ return error(unsupport);
+
+ tok++;
+ if (*tok == CONST)
+ {
+ tok++;
+ bfparam1 = *(int *)tok;
+ if (bfparam1 > 31 || bfparam1 < 0)
+ return error("bfxxx offset: immediate value must be between 0 and 31");
+ bfparam1 = (bfparam1 << 6) | (0 << 11); //Do=0, offset=immediate - shift it to place
+ tok++;
+ }
+ else if (*tok == SYMBOL)
+ {
+ if (expr(bf0expr, &bf0exval, &bf0exattr, &bf0esym) != OK)
+ return ERROR;
+ bfparam1 = bf0exval;
+ if (bfparam1 > 31 || bfparam1 < 0)
+ return error("bfxxx offset: immediate value must be between 0 and 31");
+ bfparam1 = (bfparam1 << 6) | (0 << 11); //Do=0, offset=immediate - shift it to place
+ }
+ else if (*tok >= KW_D0 && *tok <= KW_D7)
+ {
+ bfparam1 = ((*(int *)tok - 128) << 6) | (1 << 11); //Do=1, offset=data register - shift it to place
+ tok++;
+ }
+ else
+ return ERROR;
+
+ if (*tok==':')
+ tok++; //eat the ':'
+
+ if (*tok == '}' && tok[1] == EOL)
+ {
+ tok++;
+ return OK; //It is ok to have }, EOL here - it might be "fmove fpn,<ea> {dx}"
+ }
+
+
+ if (*tok == CONST)
+ {
+ tok++;
+ bfparam2 = *(int *)tok;
+ if (bfparam2 > 31 || bfparam2 < 0)
+ return error("bfxxx width: immediate value must be between 0 and 31");
+ bfparam2 = (bfparam2 << 0) | (0 << 5); //Do=0, offset=immediate - shift it to place
+ tok++;
+ }
+ else if (*tok == SYMBOL)
+ {
+ if (expr(bf0expr, &bf0exval, &bf0exattr, &bf0esym) != OK)
+ return ERROR;
+ bfparam2 = bf0exval;
+ if (bfparam2 > 31 || bfparam2 < 0)
+ return error("bfxxx width: immediate value must be between 0 and 31");
+ bfparam2 = (bfparam2 << 0) | (0 << 5); //Do=0, offset=immediate - shift it to place
+ }
+ else if (*tok >= KW_D0 && *tok <= KW_D7)
+ {
+ bfparam2 = ((*(int *)tok - 128) << 0) | (1 << 5); //Do=1, offset=data register - shift it to place
+ tok++;
+ }
+ else
+ return ERROR;
+
+ tok++; //eat the '}'
+
+ return OK;
+}
#define AM_SR 0107
#define AM_CCR 0110
#define AM_NONE 0111 // Nothing
+#define CACHES 0120 // Instruction/Data/Both Caches (IC/DC/BC)
+#define CREG 0121 // Control registers (see CREGlut in mach.h)
+#define FREG 0122 // FPU registers (fp0-fp7)
+#define FPSCR 0123 // FPU system control registers (fpiar, fpsr, fpcr)
// Addressing-mode masks
#define M_DREG 0x00000001L // Dn
#define M_IMMED 0x00000800L // #data
#define M_ABASE 0x00001000L // (bd,An,Xn)
#define M_MEMPOST 0x00002000L // ([bd,An],Xn,od)
-#define M_MEMPRE 0x00004000L // ([bc,An,Xn],od)
+#define M_MEMPRE 0x00004000L // ([bd,An,Xn],od)
#define M_PCBASE 0x00008000L // (bd,PC,Xn)
#define M_PCMPOST 0x00010000L // ([bd,PC],Xn,od)
#define M_PCMPRE 0x00020000L // ([bc,PC,Xn],od)
#define M_AM_SR 0x00080000L // SR
#define M_AM_CCR 0x00100000L // CCR
#define M_AM_NONE 0x00200000L // (nothing)
+#define M_BITFLD 0x00400000L // 68020 bitfield
+#define M_CREG 0x00800000L // Control registers
+#define M_FREG 0x01000000L // FPn
+#define M_FPSCR 0x02000000L // fpiar, fpsr, fpcr
// Addr mode categories
#define C_ALL 0x00000FFFL
#define C_MEM 0x00000FFCL
#define C_CTRL 0x000007E4L
#define C_ALT 0x000001FFL
+#define C_ALL030 0x0003FFFFL
+#define C_CTRL030 0x0003F7E4L
+#define C_DATA030 0x0003FFFDL
+#define C_MOVES (M_AIND|M_APOSTINC|M_APREDEC|M_ADISP|M_AINDEXED|M_ABSW|M_ABSL|M_ABASE|M_MEMPRE|M_MEMPOST)
#define C_ALTDATA (C_DATA&C_ALT)
#define C_ALTMEM (C_MEM&C_ALT)
#define C_LABEL (M_ABSW|M_ABSL)
#define C_NONE M_AM_NONE
+#define C_CREG (M_AM_USP|M_CREG)
+
// Scales
#define TIMES1 00000 // (empty or *1)
#define TIMES2 01000 // *2
#define TIMES4 02000 // *4
#define TIMES8 03000 // *8
+#define M_FC (M_IMMED|M_DREG|M_CREG)
+#define M_MRN (M_DREG|M_AREG|M_CREG)
+
+//EA extension word
+#define EXT_D 0x0000 // Dn
+#define EXT_A 0x8000 // An
+#define EXT_W 0x0000 // Index Size Sign-Extended Word
+#define EXT_L 0x0800 // Index Size Long Word
+#define EXT_TIMES1 0x0000 // Scale factor 1
+#define EXT_TIMES2 0x0200 // Scale factor 2
+#define EXT_TIMES4 0x0400 // Scale factor 4
+#define EXT_TIMES8 0x0600 // Scale factor 8
+#define EXT_FULLWORD 0x0100 // Use full extension word format
+#define EXT_BS 0x0080 // Base Register Suppressed
+#define EXT_IS 0x0040 // Index Operand Suppressed
+#define EXT_BDSIZE0 0x0010 // Base Displacement Size Null (Suppressed)
+#define EXT_BDSIZEW 0x0020 // Base Displacement Size Word
+#define EXT_BDSIZEL 0x0030 // Base Displacement Size Long
+#define EXT_IISPRE0 0x0000 // Indirect and Indexing Operand - No Memory Indirect Action
+#define EXT_IISPREN 0x0001 // Indirect and Indexing Operand - Indirect Preindexed with Null Outer Displacement
+#define EXT_IISPREW 0x0002 // Indirect and Indexing Operand - Indirect Preindexed with Word Outer Displacement
+#define EXT_IISPREL 0x0003 // Indirect and Indexing Operand - Indirect Preindexed with Long Outer Displacement
+#define EXT_IISPOSN 0x0005 // Indirect and Indexing Operand - Indirect Postindexed with Null Outer Displacement
+#define EXT_IISPOSW 0x0006 // Indirect and Indexing Operand - Indirect Postindexed with Word Outer Displacement
+#define EXT_IISPOSL 0x0007 // Indirect and Indexing Operand - Indirect Postindexed with Long Outer Displacement
+#define EXT_IISNOI0 0x0000 // Indirect and Indexing Operand - No Memory Indirect Action
+#define EXT_IISNOIN 0x0001 // Indirect and Indexing Operand - Memory Indirect with Null Outer Displacement
+#define EXT_IISNOIW 0x0002 // Indirect and Indexing Operand - Memory Indirect with Word Outer Displacement
+#define EXT_IISNOIL 0x0003 // Indirect and Indexing Operand - Memory Indirect with Long Outer Displacement
+
#define EXPRSIZE 128 // Maximum #tokens in an expression
// Addressing mode variables, output of amode()
extern int nmodes;
extern int am0, am1;
-extern int a0reg, a1reg;
+extern int a0reg, a1reg, a2reg;
extern TOKEN a0expr[], a1expr[];
extern VALUE a0exval, a1exval;
extern WORD a0exattr, a1exattr;
extern VALUE a0oexval, a1oexval;
extern WORD a0oexattr, a1oexattr;
extern SYM * a0esym, * a1esym;
+extern VALUE a0bexval, a1bexval;
+extern WORD a0bexattr, a1bexattr;
+extern WORD a0bsize, a1bsize;
+extern TOKEN a0bexpr[], a1bexpr[];
+extern WORD a0extension, a1extension;
// Mnemonic table structure
#define MNTAB struct _mntab
// Exported functions
int amode(int);
int reglist(WORD *);
-
+int fpu_reglist_left(WORD *);
+int fpu_reglist_right(WORD *);
#endif // __AMODE_H__
int d_cstruct(void);
int d_prgflags(void);
int d_opt(void);
+int d_dsp(void);
// Directive handler table
int (*dirtab[])() = {
d_nojpad, // 55 .nojpad (deprecated)
d_gpumain, // 56 .gpumain (deprecated)
d_prgflags, // 57 .prgflags
+ d_68020, // 58 .68020
+ d_68030, // 59 .68030
+ d_68040, // 60 .68040
+ d_68060, // 61 .68060
+ d_68881, // 62 .68881
+ d_68882, // 63 .68882
+ d_56001, // 64 .56001
+ d_nofpu, // 65 nofpu
d_opt, // 58 .opt
};
}
else
{
+ if (tdb)
+ return error("non-absolute byte value");
+
if (eval + 0x100 >= 0x200)
{
sprintf(buffer, "%s (value = $%X)", range_error, eval);
return error(buffer);
}
- if (tdb)
- return error("non-absolute byte value");
-
D_byte(eval);
}
orgwarning = 0;
SaveSection();
SwitchSection(TEXT);
+ activecpu=CPU_68000;
return 0;
}
+//
+// .68020 - Back to 68000 TEXT segment and select 68020
+//
+int d_68020(void)
+{
+ d_68000();
+ activecpu=CPU_68020;
+ return 0;
+}
+
+//
+// .68030 - Back to 68000 TEXT segment and select 68030
+//
+int d_68030(void)
+{
+ d_68000();
+ activecpu=CPU_68030;
+ return 0;
+}
+
+//
+// .68040 - Back to 68000 TEXT segment and select 68040
+//
+int d_68040(void)
+{
+ d_68000();
+ activecpu=CPU_68040;
+ activefpu=FPU_68040;
+ return 0;
+}
+
+//
+// .68060 - Back to 68000 TEXT segment and select 68060
+//
+int d_68060(void)
+{
+ d_68000();
+ activecpu=CPU_68060;
+ activefpu=FPU_68040;
+ return 0;
+}
+
+//
+// .68881 - Back to 68000 TEXT segment and select 68881 FPU
+//
+int d_68881(void)
+{
+ d_68000();
+ activefpu=FPU_68881;
+ return 0;
+}
+
+//
+// .68882 - Back to 68000 TEXT segment and select 68882 FPU
+//
+int d_68882(void)
+{
+ d_68000();
+ activefpu=FPU_68881;
+ return 0;
+}
+
+//
+// nofpu - Deselect FPUs.
+//
+int d_nofpu(void)
+{
+ activefpu=FPU_NONE;
+ return 0;
+}
+
+//
+// DSP56001
+//
+int d_56001(void)
+{
+ return error("Not yet, child. Be patient.");
+}
//
// .gpu - Switch to GPU assembler
int symlist(int(*)());
int d_even(void);
+int d_6502(void);
+int d_68000(void);
+int d_68020(void);
+int d_68030(void);
+int d_68040(void);
+int d_68060(void);
+int d_68881(void);
+int d_68882(void);
+int d_56001(void);
+int d_nofpu(void);
+int d_bss(void);
+int d_data(void);
+int d_text(void);
+int d_abs(void);
+int d_comm(void);
+int d_dc(WORD);
+int d_ds(WORD);
+int d_dcb(WORD);
+int d_globl(void);
+int d_gpu(void);
+int d_dsp(void);
+int d_assert(void);
+int d_if(void);
+int d_endif(void);
+int d_include(void);
+int ExitMacro(void);
+int d_list(void);
+int d_nlist(void);
+int d_title(void);
+int d_subttl(void);
+int eject(void);
+int d_error(char *);
+int d_warn(char *);
+int d_org(void);
+int d_init(WORD);
+int d_cargs(void);
+int d_undmac(void);
+int d_regbank0(void);
+int d_regbank1(void);
int d_long(void);
int d_phrase(void);
int d_dphrase(void);
int d_qphrase(void);
+int d_incbin(void);
+int d_noclear(void);
+int d_equrundef(void);
+int d_ccundef(void);
+int d_print(void);
+int d_gpumain(void);
+int d_jpad(void);
+int d_nojpad(void);
+int d_fail(void);
+int symlist(int(*)());
+int abs_expr(VALUE *);
+int d_cstruct(void);
+int d_prgflags(void);
+int d_opt(void);
#endif // __DIRECT_H__
#include "error.h"
#include "mach.h"
#include "riscasm.h"
+#include "sect.h"
#define eaNgen ea0gen
#define amN am0
#define aNixreg a0ixreg
#define aNixsiz a0ixsiz
#define AnESYM a0esym
+#define aNexten a0extension
+#define aNbdexval a0bexval
+#define aNbdexattr a0bexattr
#include "eagen0.c"
#define eaNgen ea1gen
#define aNixreg a1ixreg
#define aNixsiz a1ixsiz
#define AnESYM a1esym
+#define aNexten a1extension
+#define aNbdexval a1bexval
+#define aNbdexattr a1bexattr
#include "eagen0.c"
int eaNgen(WORD siz)
{
- VALUE v = aNexval;
- WORD w = (WORD)(aNexattr & DEFINED);
- WORD tdb = (WORD)(aNexattr & TDB);
+ VALUE vbd, v = aNexval;
+ WORD wbd, w = (WORD)(aNexattr & DEFINED);
+ WORD tdbbd, tdb = (WORD)(aNexattr & TDB);
+ vbd = aNbdexval;
+ wbd = (WORD)(aNbdexattr & DEFINED);
+ tdbbd = (WORD)(aNbdexattr & TDB);
switch (amN)
{
}
break;
+ case SIZP:
+ // 68881/68882/68040 only
+ return error("Sorry, .p constant format is not implemented yet!");
+ break;
case ABSW:
if (w) // Defined
{
case PCBASE:
case PCMPOST:
case PCMPRE:
- return error("unsupported 68020 addressing mode");
+ D_word(aNexten);
+ // Deposit bd (if not suppressed)
+ if ((aNexten&0x0030)==EXT_BDSIZE0)
+ {
+ // Don't deposit anything (suppressed)
+ }
+ else if ((aNexten&0x0030)==EXT_BDSIZEW)
+ {
+ // Deposit word bd
+ if (wbd)
+ {
+ // Just deposit it
+ if (tdb)
+ MarkRelocatable(cursect, sloc, tdbbd, MWORD, NULL);
+
+ if (vbd + 0x8000 >= 0x10000)
+ return error(range_error);
+
+ D_word(vbd);
+ }
+ else
+ {
+ // Arrange for fixup later on
+ AddFixup(FU_WORD|FU_SEXT, sloc, aNexpr);
+ D_word(0);
+ }
+ }
+ else
+ {
+ // Deposit long bd
+ if (wbd)
+ {
+ // Just deposit it
+ if (tdbbd)
+ MarkRelocatable(cursect, sloc, tdbbd, MLONG, NULL);
+
+ D_long(vbd);
+ }
+ else
+ {
+ // Arrange for fixup later on
+ AddFixup(FU_LONG|FU_SEXT, sloc, aNexpr);
+ D_long(0);
+ }
+ }
+ // Deposit od (if not suppressed)
+ if ((aNexten&7)==EXT_IISPRE0 || (aNexten&7)==EXT_IISPREN
+ || (aNexten&7)==EXT_IISNOIN || (aNexten&7)==EXT_IISPOSN)
+ {
+ // Don't deposit anything (suppressed)
+ }
+ else if ((aNexten&7)==EXT_IISPREW
+ || (aNexten&7)==EXT_IISPOSW || (aNexten&7)==EXT_IISNOIW)
+ {
+ // Deposit word od
+ if (w)
+ {
+ // Just deposit it
+ if (tdb)
+ MarkRelocatable(cursect, sloc, tdb, MWORD, NULL);
+
+ if (v + 0x8000 >= 0x10000)
+ return error(range_error);
+
+ D_word(v);
+ }
+ else
+ {
+ // Arrange for fixup later on
+ AddFixup(FU_WORD|FU_SEXT, sloc, aNexpr);
+ D_word(0);
+ }
+ }
+ else
+ {
+ // Deposit long od
+ if (w)
+ {
+ // Just deposit it
+ if (tdb)
+ MarkRelocatable(cursect, sloc, tdb, MLONG, NULL);
+
+ D_long(v);
+ }
+ else
+ {
+ // Arrange for fixup later on
+ AddFixup(FU_LONG|FU_SEXT, sloc, aNexpr);
+ D_long(0);
+ }
+ }
+
+ break;
+ //return error("unsupported 68020 addressing mode");
default:
// Bad addressing mode in ea gen
interror(3);
#undef aNexpr
#undef aNixreg
#undef aNixsiz
+#undef aNexten
+#undef aNbdexval
+#undef aNbdexattr
#undef AnESYM
#include "rmac.h"
-#define EBUFSIZ 200 // Max size of an error message
+#define EBUFSIZ 256 // Max size of an error message
// Exported variables
extern int errcnt;
*evalTokenBuffer++ = (orgactive ? orgaddr : pcloc);
// '*' takes attributes of current section, not ABS!
*evalTokenBuffer++ = cursect | DEFINED;
+ break;
+ case '{':
+ if (expr0() != OK) // Eat up first parameter (register or immediate)
+ return ERROR;
+
+ if (*tok++ != ':') // Demand a ':' there
+ return error("missing colon ':'");
+
+ if (expr0() != OK) // Eat up second parameter (register or immediate)
+ return ERROR;
+
+ if (*tok++ != '}')
+ return error("missing close bracket '}'");
+
break;
default:
return error("bad expression");
* Tunable definitions
*
*/
-#define TABSIZE 1024 /* state table size */
-#define NSTRINGS 500 /* maximum number of keywords */
+#define TABSIZE 2048 /* state table size */
+#define NSTRINGS 1024 /* maximum number of keywords */
#define STRPOOLSIZ (NSTRINGS * 10) /* size of string pool */
sr 146
ccr 147
+ic40 185
+dc40 186
+bc40 187
+
+sfc 188
+dfc 189
+vbr 191
+
+cacr 192
+caar 193
+msp 194
+isp 195
+
+tc 196
+itt0 197
+itt1 198
+dtt0 199
+dtt1 200
+mmusr 201
+urp 202
+srp 203
+
+iacr0 204
+iacr1 205
+dacr0 206
+dacr1 207
+
+tt0 208
+tt1 209
+
+crp 210
+
+fpiar 220
+fpsr 221
+fpcr 222
+
+fp0 224
+fp1 225
+fp2 226
+fp3 227
+fp4 228
+fp5 229
+fp6 230
+fp7 231
+mr 272
+omr 273
+la 274
+lc 275
+ssh 276
+ssl 277
+ss 278
+
.equ 61
equ 61
.equr 148
.regequ 148
regequ 148
set 149
+
reg 150
r0 151
r1 152
// Exported variables
int movep = 0; // Global flag to indicate we're generating a movep instruction
-// Function prototypes
-int m_unimp(WORD, WORD), m_badmode(WORD, WORD), m_bad6mode(WORD, WORD), m_bad6inst(WORD, WORD);
-int m_self(WORD, WORD);
-int m_abcd(WORD, WORD);
-int m_reg(WORD, WORD);
-int m_imm(WORD, WORD);
-int m_imm8(WORD, WORD);
-int m_shi(WORD, WORD);
-int m_shr(WORD, WORD);
-int m_bitop(WORD, WORD);
-int m_exg(WORD, WORD);
-int m_ea(WORD, WORD);
-int m_br(WORD, WORD);
-int m_dbra(WORD, WORD);
-int m_link(WORD, WORD);
-int m_adda(WORD, WORD);
-int m_addq(WORD, WORD);
-//int m_move(WORD, int);
-int m_move(WORD, WORD);
-int m_moveq(WORD, WORD);
-int m_usp(WORD, WORD);
-int m_movep(WORD, WORD);
-int m_trap(WORD, WORD);
-int m_movem(WORD, WORD);
-int m_clra(WORD, WORD);
-
// Common error messages
char range_error[] = "expression out of range";
char abs_error[] = "illegal absolute expression";
char siz_error[] = "bad size specified";
char undef_error[] = "undefined expression";
char fwd_error[] = "forward or undefined expression";
+char unsupport[] = "unsupported for selected CPU";
+
+extern int ea0gen(WORD);
+extern int ea1gen(WORD);
+extern int mulmode;
// Include code tables
MNTAB machtab[] = {
0 // SIZN
};
+// Byte/Word/long size (0=.w, 1=.l) in bit 9
+WORD lwsiz_9[] = {
+ (WORD)-1,
+ 0, // Byte
+ 1<<9, (WORD)-1, // Word
+ 1<<10, (WORD)-1, (WORD)-1, (WORD)-1, // Long
+ 1<<9 // Word (SIZN)
+};
+
// Addressing mode in bits 6..11 (register/mode fields are reversed)
WORD am_6[] = {
00000, 01000, 02000, 03000, 04000, 05000, 06000, 07000,
00700, 01700, 02700, 03700, 04700, 05700, 06700, 07700
};
+// Control registers lookup table
+WORD CREGlut[21] = {
+ // MC68010/MC68020/MC68030/MC68040/CPU32
+ 0x000, // Source Function Code(SFC)
+ 0x001, // Destination Function Code(DFC)
+ 0x800, // User Stack Pointer(USP)
+ 0x801, // Vector Base Register(VBR)
+ // MC68020 / MC68030 / MC68040
+ 0x002, // Cache Control Register(CACR)
+ 0x802, // Cache Address Register(CAAR) (020/030 only)
+ 0x803, // Master Stack Pointer(MSP)
+ 0x804, // Interrupt Stack Pointer(ISP)
+ // MC68040 / MC68LC040
+ 0x003, // MMU Translation Control Register(TC)
+ 0x004, // Instruction Transparent Translation Register 0 (ITT0)
+ 0x005, // Instruction Transparent Translation Register 1 (ITT1)
+ 0x006, // Data Transparent Translation Register 0 (DTT0)
+ 0x007, // Data Transparent Translation Register 1 (DTT1)
+ 0x805, // MMU Status Register(MMUSR)
+ 0x806, // User Root Pointer(URP)
+ 0x807, // Supervisor Root Pointer(SRP)
+ // MC68EC040 only
+ 0x004, // Instruction Access Control Register 0 (IACR0)
+ 0x005, // Instruction Access Control Register 1 (IACR1)
+ 0x006, // Data Access Control Register 0 (DACR1)
+ 0x007, // Data Access Control Register 1 (DACR1)
+ // 68851 only
+ 0xfff // CPU Root Pointer (CRP) - There's no movec with CRP in it, this is just a guard entry
+};
// Error messages
int m_unimp(WORD unused1, WORD unused2)
int m_self(WORD inst, WORD usused)
{
D_word(inst);
- return 0;
+ return OK;
}
ea1gen(siz);
}
- return 0;
+ return OK;
+}
+
+//
+// Check if lea x(an),an can be optimised to
+// addq.w #x,an - otherwise fall back to m_ea.
+//
+int m_lea(WORD inst, WORD siz)
+{
+ if (optim_flags[OPT_LEA_ADDQ])
+ if (am0==ADISP && a0reg==a1reg && (a0exattr & DEFINED))
+ if (a0exval>0 && a0exval<=8)
+ {
+ inst=B16(01010000,01001000)|((a0exval&7)<<9)|(a0reg);
+ D_word(inst);
+ warn("lea size(An),An converted to addq #size,An");
+ return OK;
+ }
+
+ return m_ea(inst,siz);
+}
+
+int m_ea030(WORD inst, WORD siz)
+{
+ CHECK00;
+
+ WORD flg = inst; // Save flag bits
+ inst &= ~0x3F; // Clobber flag bits in instr
+
+ // Install "standard" instr size bits
+ if (flg & 4)
+ inst |= siz_6[siz];
+
+ if (flg & 16)
+ {
+ // OR-in register number
+ if (flg & 8)
+ {
+ inst |= reg_9[a1reg]; // ea1reg in bits 9..11
+ }
+ else
+ {
+ inst |= reg_9[a0reg]; // ea0reg in bits 9..11
+ }
+ }
+
+ if (flg & 1)
+ {
+ // Use am1
+ inst |= am1 | a1reg; // Get ea1 into instr
+ D_word(inst); // Deposit instr
+
+ // Generate ea0 if requested
+ if (flg & 2)
+ ea0gen(siz);
+
+ ea1gen(siz); // Generate ea1
+ }
+ else
+ {
+ // Use am0
+ //inst |= am0 | a0reg; // Get ea0 into instr
+ if (am0 == AREG)
+ //We get here if we're doing 020+ addressing and an address register is used.
+ //For example, something like "tst a0". A bit of a corner case, so kludge it
+ a0reg = a0reg + 8;
+ else if (am0 == PCDISP)
+ //Another corner case (possibly!), so kludge ahoy
+ inst |= am0; // Get ea0 into instr
+ else if (am0 == IMMED)
+ inst |= am0 | a0reg; // Get ea0 into instr
+ else if (am0 == AM_CCR)
+ inst |= am1 | a1reg;
+ else if (am0 == AIND)
+ inst |= am0;
+
+ inst |= a0reg; // Get ea0 into instr
+ D_word(inst); // Deposit instr
+ ea0gen(siz); // Generate ea0
+
+ // Generate ea1 if requested
+ if (flg & 2)
+ ea1gen(siz);
+ }
+
+ return OK;
}
inst |= a0reg | reg_9[a1reg];
D_word(inst);
- return 0;
+ return OK;
}
D_word(inst);
ea0gen(siz); // Generate EA
- return 0;
+ return OK;
}
inst |= a0reg; // Install first register
D_word(inst);
- return 0;
+ return OK;
}
D_word(inst);
ea0gen(siz);
- return 0;
+ return OK;
}
D_word(inst);
ea0gen(SIZB);
- return 0;
+ return OK;
}
inst |= reg_9[a0reg] | a1reg | siz_6[siz];
D_word(inst);
- return 0;
+ return OK;
}
D_word(inst);
}
- return 0;
+ return OK;
}
// ea to bit-munch
ea1gen(SIZB);
- return 0;
+ return OK;
}
D_word(0);
}
- return 0;
+ return OK;
}
inst |= m | reg_9[a0reg] | a1reg;
D_word(inst);
- return 0;
+ return OK;
}
//
int m_link(WORD inst, WORD siz)
{
- siz = siz;
+ if (siz != SIZL)
+ {
+ }
+ else
+ {
+ CHECK00;
+ inst &= ~((3 << 9)|(1<<6)|(1<<4));
+ inst |= 1 << 3;
+ }
inst |= a0reg;
D_word(inst);
- ea1gen(SIZW);
+ ea1gen(siz);
- return 0;
+ return OK;
}
+WORD extra_addressing[16]=
+{
+ 0, //0100 (bd,An,Xn)
+ 0, //0101 ([bd,An],Xn,od)
+ 0x180, //0102 ([bc,An,Xn],od) (111 110 110 111)
+ 0, //0103 (bd,PC,Xn)
+ 0, //0104 ([bd,PC],Xn,od)
+ 0, //0105 ([bc,PC,Xn],od)
+ 0, //0106
+ 0, //0107
+ 0, //0110
+ 0, //0111 Nothing
+ 0x30, //0112 (Dn.w)
+ 0x30, //0113 (Dn.l)
+ 0, //0114
+ 0, //0115
+ 0, //0116
+ 0 //0117
+
+};
//
// Handle MOVE <C_ALL> <C_ALTDATA>
}
else
{
+ if (am0<ABASE && am1<ABASE) //68000 modes
+ {
inst |= siz_12[siz] | am_6[am1] | reg_9[a1reg] | am0 | a0reg;
D_word(inst);
if (am1 >= ADISP)
ea1gen((WORD)siz | 0x8000); // Tell ea1gen we're move ea,ea
}
+ else //68020+ modes
+ {
+ inst |= siz_12[siz] | reg_9[a1reg] | extra_addressing[am0-ABASE];
- return 0;
+ D_word(inst);
+
+ if (am0 >= ADISP)
+ ea0gen((WORD)siz);
+
+ if (am1 >= ADISP)
+ ea1gen((WORD)siz);
+ }
+ }
+
+ return OK;
+}
+
+//
+// Handle MOVE <C_ALL030> <C_ALTDATA>
+// MOVE <C_ALL030> <M_AREG>
+//
+int m_move30(WORD inst, WORD size)
+{
+ // Cast the passed in value to an int
+ int siz = (int)size;
+
+ /*if (am0<ABASE && am1<ABASE) //68000 modes
+ {
+ inst |= siz_12[siz] | am_6[am1] | reg_9[a1reg] | am0 | a0reg;
+
+ D_word(inst);
+
+ if (am0 >= ADISP)
+ ea0gen((WORD)siz);
+
+ if (am1 >= ADISP)
+ | 0x8000); // Tell ea1gen we're move ea,ea
+ }
+ else //68020+ modes
+ {*/
+ inst |= siz_12[siz] | reg_9[a1reg&7] | a0reg | extra_addressing[am0-ABASE];
+
+ D_word(inst);
+
+ if (am0 >= ADISP)
+ ea0gen((WORD)siz);
+
+ if (am1 >= ADISP)
+ ea1gen((WORD)siz);
+ /*}*/
+
+ return OK;
}
D_word(inst);
- return 0;
+ return OK;
}
inst |= reg_9[a1reg] | (a0exval & 0xFF);
D_word(inst);
- return 0;
+ return OK;
}
//
D_word(inst);
if (sbra_flag)
warn("Bcc.w/BSR.w converted to .s");
- return 0;
+ return OK;
}
else
{
D_word(inst);
D_word(v);
- return 0;
+ return OK;
}
}
- if (siz == SIZB)
+ if (siz == SIZB || siz == SIZS)
{
if (v + 0x80 >= 0x100)
return error(range_error);
D_word(v);
}
- return 0;
+ return OK;
}
else if (siz == SIZN)
siz = SIZW;
- if (siz == SIZB)
+ if (siz == SIZB || siz == SIZS)
{
// .B
AddFixup(FU_BBRA | FU_PCREL | FU_SEXT, sloc, a0expr);
D_word(inst);
- return 0;
+ return OK;
}
else
{
D_word(0);
}
- return 0;
+ return OK;
}
ea1gen(siz);
- return 0;
+ return OK;
}
else
return error(undef_error);
- return 0;
+ return OK;
}
tok++;
if (abs_expr(&eval) != OK)
- return 0;
+ return OK;
if (eval >= 0x10000L)
return error(range_error);
{
// <rlist>, ea
if (reglist(&rmask) < 0)
- return 0;
+ return OK;
immed1:
if (*tok++ != ',')
return error("missing comma");
if (amode(0) < 0)
- return 0;
+ return OK;
inst |= am0 | a0reg;
{
// ea, <rlist>
if (amode(0) < 0)
- return 0;
+ return OK;
inst |= 0x0400 | am0 | a0reg;
tok++;
if (abs_expr(&eval) != OK)
- return 0;
+ return OK;
if (eval >= 0x10000)
return error(range_error);
rmask = (WORD)eval;
}
else if (reglist(&rmask) < 0)
- return 0;
+ return OK;
if (!(amsktab[am0] & (C_CTRL | M_APOSTINC)))
return error("invalid addressing mode");
D_word(rmask);
ea0gen(siz);
- return 0;
+ return OK;
}
inst |= a0reg | reg_9[a0reg] | lwsiz_8[siz];
D_word(inst);
- return 0;
+ return OK;
+}
+
+////////////////////////////////////////
+//
+// 68020/30/40 instructions
+//
+////////////////////////////////////////
+
+//
+// Bcc.l -- BSR.l
+//
+int m_br30(WORD inst, WORD siz)
+{
+ VALUE v;
+
+ if (a0exattr & DEFINED)
+ {
+ if ((a0exattr & TDB) != cursect)
+ //{
+ //printf("m_br(): a0exattr = %X, cursect = %X, a0exval = %X, sloc = %X\n", a0exattr, cursect, a0exval, sloc);
+ return error(rel_error);
+ //}
+
+ v = a0exval - (sloc + 2);
+
+ D_word(inst);
+ D_long(v);
+
+ return OK;
+ }
+ else
+ {
+ // .L
+ AddFixup(FU_LONG | FU_PCREL | FU_SEXT, sloc, a0expr);
+ D_word(inst);
+ return OK;
+ }
+}
+
+//
+// bfchg, bfclr, bfexts, bfextu, bfffo, bfins, bfset
+// (68020, 68030, 68040)
+//
+int m_bfop(WORD inst, WORD siz)
+{
+ //TODO: is this needed or can we put that in the mask in 68ktab???
+ if (am0 == AREG || am0== APOSTINC || am0 == APREDEC || am0 == IMMED|| am0 == ABASE || am0 == MEMPOST || am0 == MEMPRE || am0 == PCBASE || am0 == PCMPOST || am0 == PCMPRE)
+ return m_badmode(inst, siz);
+
+ //First instruction word - just the opcode and first EA
+ //Note: both am1 is ORed because solely of bfins - maybe it's a good idea to make a dedicated function for it?
+ if (am1 == AM_NONE)
+ am1 = 0;
+ D_word((inst|am0|a0reg|am1|a1reg));
+ ea0gen(siz); // Generate EA
+
+ //Second instruction word - Dest register (if exists), Do, Offset, Dw, Width
+ inst = bfparam1 | bfparam2;
+ if (am1 == DREG)
+ inst |= a1reg << 12;
+ if (am0 == DREG)
+ inst |= a0reg << 12;
+ D_word(inst);
+
+ return OK;
+}
+
+//
+// bkpt (68EC000, 68010, 68020, 68030, 68040, CPU32)
+//
+int m_bkpt(WORD inst, WORD siz)
+{
+ CHECK00;
+
+ if (a0exattr & DEFINED)
+ {
+ if (a0exattr & TDB)
+ return error(abs_error);
+
+ if (a0exval >= 8)
+ return error(range_error);
+
+ inst |= a0exval;
+ D_word(inst);
+ }
+ else
+ return error(undef_error);
+
+ return OK;
+}
+
+//
+// callm (68020)
+//
+int m_callm(WORD inst, WORD siz)
+{
+ CHECKNO20;
+
+ inst |= am1;
+ D_word(inst);
+
+ if (a0exattr & DEFINED)
+ {
+ if (a0exattr & TDB)
+ return error(abs_error);
+
+ if (a0exval > 255)
+ return error(range_error);
+
+ inst = a0exval;
+ D_word(inst);
+ }
+ else
+ return error(undef_error);
+
+ ea1gen(siz);
+
+ return OK;
+
+}
+
+//
+// cas (68020, 68030, 68040)
+//
+int m_cas(WORD inst, WORD siz)
+{
+ WORD inst2;
+ LONG amsk;
+ int modes;
+
+ if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
+ return error(unsupport);
+
+ switch (siz)
+ {
+ case SIZB:
+ inst |= 1 << 9;
+ break;
+ case SIZW:
+ case SIZN:
+ inst |= 2 << 9;
+ break;
+ case SIZL:
+ inst |= 3 << 9;
+ break;
+ default:
+ return error("bad size suffix");
+ break;
+ }
+
+ // Dc
+ if ((*tok < KW_D0) && (*tok > KW_D7))
+ return error("CAS accepts only data registers");
+ inst2 = (*tok++) & 7;
+
+ if (*tok++ != ',')
+ return error("missing comma");
+
+ // Du
+ if ((*tok < KW_D0) && (*tok > KW_D7))
+ return error("CAS accepts only data registers");
+ inst2 |= ((*tok++) & 7)<<6;
+
+ if (*tok++ != ',')
+ return error("missing comma");
+
+ // ea
+ if ((modes=amode(1)) < 0)
+ return OK;
+
+ if (modes > 1)
+ return error("too many ea fields");
+
+ if (*tok!=EOL)
+ return error("extra (unexpected) text found");
+
+ // Reject invalud ea modes
+ amsk = amsktab[am0];
+ if (amsk&(M_AIND | M_APOSTINC | M_APREDEC | M_ADISP | M_AINDEXED | M_ABSW | M_ABSL | M_ABASE | M_MEMPOST | M_MEMPRE) == 0)
+ return error("unsupported addressing mode");
+
+ inst |= am0 | a0reg;
+ D_word(inst);
+ D_word(inst2);
+ ea0gen(siz);
+
+ return OK;
+}
+
+//
+// cas2 (68020, 68030, 68040)
+//
+int m_cas2(WORD inst, WORD siz)
+{
+ WORD inst2, inst3;
+ LONG amsk;
+
+ if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
+ return error(unsupport);
+
+ switch (siz)
+ {
+ case SIZB:
+ inst |= 1 << 9;
+ break;
+ case SIZW:
+ case SIZN:
+ inst |= 2 << 9;
+ break;
+ case SIZL:
+ inst |= 3 << 9;
+ break;
+ default:
+ return error("bad size suffix");
+ break;
+ }
+
+ // Dc1
+ if ((*tok < KW_D0) && (*tok > KW_D7))
+ return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
+ inst2 = (*tok++) & 7;
+
+ if (*tok++ != ':')
+ return error("missing colon");
+
+ // Dc2
+ if ((*tok < KW_D0) && (*tok > KW_D7))
+ return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
+ inst3 = (*tok++) & 7;
+
+ if (*tok++ != ',')
+ return error("missing comma");
+
+ // Du1
+ if ((*tok < KW_D0) && (*tok > KW_D7))
+ return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
+ inst2 |= ((*tok++) & 7)<<6;
+
+ if (*tok++ != ':')
+ return error("missing colon");
+
+ // Du2
+ if ((*tok < KW_D0) && (*tok > KW_D7))
+ return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
+ inst3 |= ((*tok++) & 7) << 6;
+
+ if (*tok++ != ',')
+ return error("missing comma");
+
+ // Rn1
+ if (*tok++ != '(')
+ return error("missing (");
+ if ((*tok >= KW_D0) && (*tok <= KW_D7))
+ inst2 |= (((*tok++) & 7) << 12) | (0 << 15);
+ else if ((*tok >= KW_A0) && (*tok <= KW_A7))
+ inst2 |= (((*tok++) & 7) << 12) | (1 << 15);
+ else
+ return error("CAS accepts either data or address registers for Rn1:Rn2 pair");
+
+ if (*tok++ != ')')
+ return error("missing (");
+
+ if (*tok++ != ':')
+ return error("missing colon");
+
+ // Rn2
+ if (*tok++ != '(')
+ return error("missing (");
+ if ((*tok >= KW_D0) && (*tok <= KW_D7))
+ inst3 |= (((*tok++) & 7) << 12) | (0 << 15);
+ else if ((*tok >= KW_A0) && (*tok <= KW_A7))
+ inst3 |= (((*tok++) & 7) << 12) | (1 << 15);
+ else
+ return error("CAS accepts either data or address registers for Rn1:Rn2 pair");
+
+ if (*tok++ != ')')
+ return error("missing (");
+
+ if (*tok != EOL)
+ return error("extra (unexpected) text found");
+
+ D_word(inst);
+ D_word(inst2);
+ D_word(inst3);
+
+ return OK;
+}
+
+//
+// cmp2 (68020, 68030, 68040, CPU32)
+//
+int m_cmp2(WORD inst, WORD siz)
+{
+ if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
+ return error(unsupport);
+
+ switch (siz&15)
+ {
+ case SIZW:
+ case SIZN:
+ inst |= 1 << 9;
+ break;
+ case SIZL:
+ inst |= 2 << 9;
+ break;
+ default:
+ // SIZB
+ break;
+ }
+
+ WORD flg = inst; // Save flag bits
+ inst &= ~0x3F; // Clobber flag bits in instr
+
+ // Install "standard" instr size bits
+ if (flg & 4)
+ inst |= siz_6[siz];
+
+ if (flg & 16)
+ {
+ // OR-in register number
+ if (flg & 8)
+ inst |= reg_9[a1reg]; // ea1reg in bits 9..11
+ else
+ inst |= reg_9[a0reg]; // ea0reg in bits 9..11
+ }
+
+ if (flg & 1)
+ {
+ // Use am1
+ inst |= am1 | a1reg; // Get ea1 into instr
+ D_word(inst); // Deposit instr
+
+ // Generate ea0 if requested
+ if (flg & 2)
+ ea0gen(siz);
+
+ ea1gen(siz); // Generate ea1
+ }
+ else
+ {
+ // Use am0
+ inst |= am0 | a0reg; // Get ea0 into instr
+ D_word(inst); // Deposit instr
+ ea0gen(siz); // Generate ea0
+
+ // Generate ea1 if requested
+ if (flg & 2)
+ ea1gen(siz);
+ }
+
+ // If we're called from chk2 then bit 11 of size will be set.
+ // This is just a dumb mechanism to pass this, required by the extension word.
+ // (you might have noticed the siz&15 thing above!)
+ inst = (a1reg << 12)|(siz&(1<<11));
+ if (am1 == AREG)
+ inst |= 1 << 15;
+
+ D_word(inst);
+
+ return OK;
+}
+
+//
+// chk2 (68020, 68030, 68040, CPU32)
+//
+int m_chk2(WORD inst, WORD siz)
+{
+ return m_cmp2(inst, siz | (1 << 11));
+}
+
+//
+// cpbcc(68020, 68030)
+//
+int m_cpbr(WORD inst, WORD siz)
+{
+ if ((activecpu & (CPU_68020 | CPU_68030)) == 0)
+ return error(unsupport);
+
+ VALUE v;
+
+ if (a0exattr & DEFINED)
+ {
+ if ((a0exattr & TDB) != cursect)
+//{
+//printf("m_br(): a0exattr = %X, cursect = %X, a0exval = %X, sloc = %X\n", a0exattr, cursect, a0exval, sloc);
+ return error(rel_error);
+//}
+
+ v = a0exval - (sloc + 2);
+
+ // Optimize branch instr. size
+ if (siz == SIZL)
+ {
+ if (v != 0 && v + 0x8000 < 0x10000)
+ {
+ inst |= (1 << 6);
+ D_word(inst);
+ WARNING(check what s "optional coprocessor-defined extension words!")
+ D_long(v);
+ return OK;
+ }
+ }
+ else // SIZW/SIZN
+ {
+ if (v + 0x8000 >= 0x10000)
+ return error(range_error);
+ D_word(inst);
+ WARNING(check what s "optional coprocessor-defined extension words!")
+ D_word(v);
+ }
+
+ return OK;
+ }
+ else if (siz == SIZN)
+ siz = SIZW;
+
+ if (siz == SIZL)
+ {
+ // .L
+ D_word(inst);
+ AddFixup(FU_LONG | FU_PCREL | FU_SEXT, sloc, a0expr);
+ D_long(0);
+ return OK;
+ }
+ else
+ {
+ // .W
+ D_word(inst);
+ AddFixup(FU_WORD | FU_PCREL | FU_SEXT, sloc, a0expr);
+ D_word(0);
+ }
+
+ return OK;
+}
+
+//
+// cpdbcc(68020, 68030)
+//
+int m_cpdbr(WORD inst, WORD siz)
+{
+ if ((activecpu & (CPU_68020 | CPU_68030)) == 0)
+ return error(unsupport);
+
+ return error("Not implemented yet.");
+
+ //return OK;
+}
+
+//
+// divs.l
+//
+int m_divs(WORD inst, WORD siz)
+{
+ if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
+ return error(unsupport);
+
+ WORD flg = inst; // Save flag bits
+ inst &= ~0x3F; // Clobber flag bits in instr
+
+ // Install "standard" instr size bits
+ if (flg & 4)
+ inst |= siz_6[siz];
+
+ if (flg & 16)
+ {
+ // OR-in register number
+ if (flg & 8)
+ inst |= reg_9[a1reg]; // ea1reg in bits 9..11
+ else
+ inst |= reg_9[a0reg]; // ea0reg in bits 9..11
+ }
+
+ if (flg & 1)
+ {
+ // Use am1
+ inst |= am1 | a1reg; // Get ea1 into instr
+ D_word(inst); // Deposit instr
+
+ // Generate ea0 if requested
+ if (flg & 2)
+ ea0gen(siz);
+
+ ea1gen(siz); // Generate ea1
+ }
+ else
+ {
+ // Use am0
+ inst |= am0 | a0reg; // Get ea0 into instr
+ D_word(inst); // Deposit instr
+ ea0gen(siz); // Generate ea0
+
+ // Generate ea1 if requested
+ if (flg & 2)
+ ea1gen(siz);
+ }
+
+ //D_word(inst);
+ //ea0gen(siz);
+ inst=a1reg+(a2reg<<12)+(1<<11);
+ D_word(inst);
+
+ return OK;
+}
+//
+// muls.l
+//
+int m_muls(WORD inst, WORD siz)
+{
+ if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
+ return error(unsupport);
+
+ WORD flg = inst; // Save flag bits
+ inst &= ~0x3F; // Clobber flag bits in instr
+
+ // Install "standard" instr size bits
+ if (flg & 4)
+ inst |= siz_6[siz];
+
+ if (flg & 16)
+ {
+ // OR-in register number
+ if (flg & 8)
+ inst |= reg_9[a1reg]; // ea1reg in bits 9..11
+ else
+ inst |= reg_9[a0reg]; // ea0reg in bits 9..11
+ }
+
+ if (flg & 1)
+ {
+ // Use am1
+ inst |= am1 | a1reg; // Get ea1 into instr
+ D_word(inst); // Deposit instr
+
+ // Generate ea0 if requested
+ if (flg & 2)
+ ea0gen(siz);
+
+ ea1gen(siz); // Generate ea1
+ }
+ else
+ {
+ // Use am0
+ inst |= am0 | a0reg; // Get ea0 into instr
+ D_word(inst); // Deposit instr
+ ea0gen(siz); // Generate ea0
+
+ // Generate ea1 if requested
+ if (flg & 2)
+ ea1gen(siz);
+ }
+
+ //D_word(inst);
+ //ea0gen(siz);
+ inst=a1reg+(a2reg<<12)+(1<<11);
+ inst|=mulmode; // add size bit
+ D_word(inst);
+
+ return OK;
+}
+//
+// divu.l
+//
+int m_divu(WORD inst, WORD siz)
+{
+ if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
+ return error(unsupport);
+
+ //WARNING("divu.l d0,d1 is actually divul.l d0,d1:d1!!!")
+
+ WORD flg = inst; // Save flag bits
+ inst &= ~0x3F; // Clobber flag bits in instr
+
+ // Install "standard" instr size bits
+ if (flg & 4)
+ inst |= siz_6[siz];
+
+ if (flg & 16)
+ {
+ // OR-in register number
+ if (flg & 8)
+ inst |= reg_9[a1reg]; // ea1reg in bits 9..11
+ else
+ inst |= reg_9[a0reg]; // ea0reg in bits 9..11
+ }
+
+ if (flg & 1)
+ {
+ // Use am1
+ inst |= am1 | a1reg; // Get ea1 into instr
+ D_word(inst); // Deposit instr
+
+ // Generate ea0 if requested
+ if (flg & 2)
+ ea0gen(siz);
+
+ ea1gen(siz); // Generate ea1
+ }
+ else
+ {
+ // Use am0
+ inst |= am0 | a0reg; // Get ea0 into instr
+ D_word(inst); // Deposit instr
+ ea0gen(siz); // Generate ea0
+
+ // Generate ea1 if requested
+ if (flg & 2)
+ ea1gen(siz);
+ }
+
+ //D_word(inst);
+ //ea0gen(siz);
+ inst=a1reg+(a2reg<<12);
+ D_word(inst);
+
+ return OK;
+}
+//
+// mulu.l
+//
+int m_mulu(WORD inst, WORD siz)
+{
+ if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
+ return error(unsupport);
+
+ WORD flg = inst; // Save flag bits
+ inst &= ~0x3F; // Clobber flag bits in instr
+
+ // Install "standard" instr size bits
+ if (flg & 4)
+ inst |= siz_6[siz];
+
+ if (flg & 16)
+ {
+ // OR-in register number
+ if (flg & 8)
+ inst |= reg_9[a1reg]; // ea1reg in bits 9..11
+ else
+ inst |= reg_9[a0reg]; // ea0reg in bits 9..11
+ }
+
+ if (flg & 1)
+ {
+ // Use am1
+ inst |= am1 | a1reg; // Get ea1 into instr
+ D_word(inst); // Deposit instr
+
+ // Generate ea0 if requested
+ if (flg & 2)
+ ea0gen(siz);
+
+ ea1gen(siz); // Generate ea1
+ }
+ else
+ {
+ // Use am0
+ inst |= am0 | a0reg; // Get ea0 into instr
+ D_word(inst); // Deposit instr
+ ea0gen(siz); // Generate ea0
+
+ // Generate ea1 if requested
+ if (flg & 2)
+ ea1gen(siz);
+ }
+
+ //D_word(inst);
+ //ea0gen(siz);
+ inst=a1reg+(a2reg<<12);
+ inst|=mulmode; // add size bit
+ D_word(inst);
+
+ return OK;
+}
+
+//
+// divsl.l
+//
+int m_divsl(WORD inst, WORD siz)
+{
+ if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
+ return error(unsupport);
+
+ WORD flg = inst; // Save flag bits
+ inst &= ~0x3F; // Clobber flag bits in instr
+
+ // Install "standard" instr size bits
+ if (flg & 4)
+ inst |= siz_6[siz];
+
+ if (flg & 16)
+ {
+ // OR-in register number
+ if (flg & 8)
+ inst |= reg_9[a1reg]; // ea1reg in bits 9..11
+ else
+ inst |= reg_9[a0reg]; // ea0reg in bits 9..11
+ }
+
+ if (flg & 1)
+ {
+ // Use am1
+ inst |= am1 | a1reg; // Get ea1 into instr
+ D_word(inst); // Deposit instr
+
+ // Generate ea0 if requested
+ if (flg & 2)
+ ea0gen(siz);
+
+ ea1gen(siz); // Generate ea1
+ }
+ else
+ {
+ // Use am0
+ inst |= am0 | a0reg; // Get ea0 into instr
+ D_word(inst); // Deposit instr
+ ea0gen(siz); // Generate ea0
+
+ // Generate ea1 if requested
+ if (flg & 2)
+ ea1gen(siz);
+ }
+
+ //D_word(inst);
+ //ea0gen(siz);
+ inst=a1reg+(a2reg<<12)+(1<<11)+(1<<10);
+ D_word(inst);
+
+ return OK;
+}
+
+//
+// divul.l
+//
+int m_divul(WORD inst, WORD siz)
+{
+ if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
+ return error(unsupport);
+
+ WORD flg = inst; // Save flag bits
+ inst &= ~0x3F; // Clobber flag bits in instr
+
+ // Install "standard" instr size bits
+ if (flg & 4)
+ inst |= siz_6[siz];
+
+ if (flg & 16)
+ {
+ // OR-in register number
+ if (flg & 8)
+ inst |= reg_9[a1reg]; // ea1reg in bits 9..11
+ else
+ inst |= reg_9[a0reg]; // ea0reg in bits 9..11
+ }
+
+ if (flg & 1)
+ {
+ // Use am1
+ inst |= am1 | a1reg; // Get ea1 into instr
+ D_word(inst); // Deposit instr
+
+ // Generate ea0 if requested
+ if (flg & 2)
+ ea0gen(siz);
+
+ ea1gen(siz); // Generate ea1
+ }
+ else
+ {
+ // Use am0
+ inst |= am0 | a0reg; // Get ea0 into instr
+ D_word(inst); // Deposit instr
+ ea0gen(siz); // Generate ea0
+
+ // Generate ea1 if requested
+ if (flg & 2)
+ ea1gen(siz);
+ }
+
+ //D_word(inst);
+ //ea0gen(siz);
+ inst=a1reg+(a2reg<<12)+(1<<10);
+ D_word(inst);
+
+ return OK;
+}
+
+//
+// move16 (ax)+,(ay)+
+//
+int m_move16a(WORD inst, WORD siz)
+{
+ if ((activecpu & (CPU_68040 | CPU_68060)) == 0)
+ return error(unsupport);
+
+ inst|=a0reg;
+ D_word(inst);
+ inst=(1<<15)+(a1reg<<12);
+ D_word(inst);
+
+ return OK;
+}
+
+//
+// move16 with absolute address
+//
+int m_move16b(WORD inst, WORD siz)
+{
+ if ((activecpu & (CPU_68040 | CPU_68060)) == 0)
+ return error(unsupport);
+
+ int v;
+ inst|=a1reg;
+ D_word(inst);
+
+ if (am0==APOSTINC)
+ if (am1==AIND)
+ return error("Wasn't this suppose to call m_move16a???");
+ else
+ {
+ //move16 (ax)+,(xxx).L
+ inst|=0<<3;
+ v=a1exval;
+ }
+ else if (am0==ABSL)
+ if (am1==AIND)
+ {
+ //move16 (xxx).L,(ax)+
+ inst|=1<<3;
+ v=a0exval;
+ }
+ else //APOSTINC
+ {
+ //move16 (xxx).L,(ax)
+ inst|=3<<3;
+ v=a0exval;
+ }
+ else if (am0==AIND)
+ {
+ //move16 (ax),(xxx).L
+ inst|=2<<3;
+ v=a1exval;
+ }
+ D_word(inst);
+ D_long(v);
+ return OK;
+}
+
+//
+// pack/unpack
+//
+int m_pack(WORD inst, WORD siz)
+{
+ if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
+ return error(unsupport);
+
+ WARNING(Parsing stuff by hand here might be better)
+
+ //if (am0==DREG && am1==DREG)
+ //{
+ // inst|=(1<<3)+(a0reg<<9)+(a1reg);
+ //}
+ //else if (am0==APREDEC && am1==APREDEC)
+ //{
+ // inst|=(a0reg<<9)+(a1reg);
+ //}
+ //else
+ // return error("Only allowed combinations for pack/unpack are -(ax),-(ay) and dx,dy.");
+ //
+ //D_word(inst);
+
+ return OK;
+}
+
+//
+// rtm Rn
+//
+int m_rtm(WORD inst, WORD siz)
+{
+ CHECKNO20;
+
+ if (am0==DREG)
+ {
+ inst|=a0reg;
+ }
+ else if (am0==AREG)
+ {
+ inst|=(1<<3)+a0reg;
+ }
+ else
+ return error("rtm only allows data or address registers.");
+
+ D_word(inst);
+
+ return OK;
+}
+
+//
+// rtd #n
+//
+int m_rtd(WORD inst, WORD siz)
+{
+ CHECK00;
+
+ if (a0exattr & DEFINED)
+ {
+ if (a0exattr & TDB)
+ return error(abs_error);
+
+ if (a0exval+0x8000 <= 0x7fff)
+ return error(range_error);
+
+ D_word(inst);
+ D_word(a0exval);
+ }
+ else
+ return error(undef_error);
+
+ return OK;
+}
+
+
+//
+// trapcc
+//
+int m_trapcc(WORD inst, WORD siz)
+{
+ CHECK00;
+
+ if (am0==AM_NONE)
+ {
+ D_word(inst);
+ }
+ else if (am0==IMMED)
+ {
+ if (siz==SIZW)
+ {
+ if (a0exval<0x10000)
+ {
+ inst|=2;
+ D_word(inst);
+ D_word(a0exval);
+ }
+ else
+ {
+ return error("Immediate value too big");
+ }
+ }
+ else //DOTL
+ {
+ inst|=3;
+ D_word(inst);
+ D_long(a0exval);
+ }
+ }
+ else
+ return error("Invalid parameter for trapcc");
+
+ return OK;
+}
+
+//
+// cinv (68040)
+//
+int m_cinv(WORD inst, WORD siz)
+{
+ CHECKNO40;
+
+ WARNING("cinvl ,(an) / cinvp ,(an) / cinva should work!")
+ if (am0==AM_NONE)
+ inst|=(0<<6)|(a1reg);
+ else if (am0==KW_IC40)
+ inst|=(2<<6)|(a1reg);
+ else if (am0==KW_DC40)
+ inst|=(1<<6)|(a1reg);
+ else if (am0==KW_BC40)
+ inst|=(3<<6)|(a1reg);
+
+ D_word(inst);
+ return OK;
+
+}
+
+//
+// cpRESTORE (68020, 68030)
+//
+int m_cprest(WORD inst, WORD siz)
+{
+ if (activecpu & !(CPU_68020|CPU_68030))
+ return error(unsupport);
+
+ inst|=am0|a0reg;
+ D_word(inst);
+ ea0gen(siz);
+
+ return OK;
+}
+
+//
+// movec (68010, 68020, 68030, 68040, CPU32)
+//
+int m_movec(WORD inst, WORD siz)
+{
+ CHECK00;
+
+ if (am0 == DREG || am0 == AREG)
+ {
+ // movec Rn,Rc
+ inst|=1;
+ D_word(inst);
+ if (am0 == DREG)
+ {
+ inst = (0 << 15) + (a0reg << 12) + CREGlut[a1reg];
+ D_word(inst);
+ }
+ else
+ {
+ inst = (1 << 15) + (a0reg << 12) + CREGlut[a1reg];
+ D_word(inst);
+ }
+ }
+ else
+ {
+ // movec Rc,Rn
+ D_word(inst);
+ if (am1 == DREG)
+ {
+ inst = (0 << 15) + (a1reg << 12) + CREGlut[a0reg];
+ D_word(inst);
+ }
+ else
+ {
+ inst = (1 << 15) + (a1reg << 12) + CREGlut[a0reg];
+ D_word(inst);
+ }
+ }
+
+ return OK;
+}
+
+//
+// moves (68010, 68020, 68030, 68040, CPU32)
+//
+int m_moves(WORD inst, WORD siz)
+{
+ if (activecpu & !(CPU_68020 | CPU_68030 | CPU_68040))
+ return error(unsupport);
+
+ if (siz == SIZB)
+ {
+ inst |= 0 << 6;
+ }
+ else if (siz == SIZL)
+ {
+ inst |= 2 << 6;
+ }
+ else // SIZW/SIZN
+ {
+ inst |= 1 << 6;
+ }
+
+ if (am0 == DREG)
+ {
+ inst |= am1 | a1reg;
+ D_word(inst);
+ inst = (a0reg << 12) | (1 << 11) | (0 << 15);
+ D_word(inst);
+ }
+ else if (am0 == AREG)
+ {
+ inst |= am1 | a1reg;
+ D_word(inst);
+ inst = (a0reg << 12) | (1 << 11) | (1 << 15);
+ D_word(inst);
+ }
+ else
+ {
+ if (am1 == DREG)
+ {
+ inst |= am0 | a0reg;
+ D_word(inst);
+ inst = (a1reg << 12) | (0 << 11) | (0 << 15);
+ D_word(inst);
+ }
+ else
+ {
+ inst |= am0 | a0reg;
+ D_word(inst);
+ inst = (a1reg << 12) | (0 << 11) | (1 << 15);
+ D_word(inst);
+ }
+ }
+
+ return OK;
+
+}
+
+//
+// PBcc (MC68851)
+//
+int m_pbcc(WORD inst, WORD siz)
+{
+ CHECKNO20;
+ return error("Not implemented yet.");
+}
+
+//
+// pflusha (68030)
+//
+int m_pflusha(WORD inst, WORD siz)
+{
+ CHECKNO30;
+
+ D_word(inst);
+ inst=((1 << 13) | (1 << 10)) | (0 << 5) | 0;
+ D_word(inst);
+ return OK;
+}
+
+//
+// pflush (68030, 68040, 68060)
+//
+int m_pflush(WORD inst, WORD siz)
+{
+ if (activecpu == CPU_68030)
+ {
+ D_word(inst);
+ D_word(((1 << 13) | (1 << 10)) | (0 << 5) | 0);
+ }
+ else if (activecpu == CPU_68040 || activecpu == CPU_68060)
+ {
+ D_word(0xf918);
+ }
+ else
+ return error(unsupport);
+
+ return OK;
+}
+
+//
+// pflushr (68551)
+//
+int m_pflushr(WORD inst, WORD siz)
+{
+ CHECKNO20;
+
+ WORD flg = inst; // Save flag bits
+ inst &= ~0x3F; // Clobber flag bits in instr
+
+ // Install "standard" instr size bits
+ if (flg & 4)
+ inst |= siz_6[siz];
+
+ if (flg & 16)
+ {
+ // OR-in register number
+ if (flg & 8)
+ inst |= reg_9[a1reg]; // ea1reg in bits 9..11
+ else
+ inst |= reg_9[a0reg]; // ea0reg in bits 9..11
+ }
+
+ if (flg & 1)
+ {
+ // Use am1
+ inst |= am1 | a1reg; // Get ea1 into instr
+ D_word(inst); // Deposit instr
+
+ // Generate ea0 if requested
+ if (flg & 2)
+ ea0gen(siz);
+
+ ea1gen(siz); // Generate ea1
+ }
+ else
+ {
+ // Use am0
+ inst |= am0 | a0reg; // Get ea0 into instr
+ D_word(inst); // Deposit instr
+ ea0gen(siz); // Generate ea0
+
+ // Generate ea1 if requested
+ if (flg & 2)
+ ea1gen(siz);
+ }
+
+ D_word(B16(10100000, 00000000));
+}
+
+//
+// ploadr, ploadw (68030)
+//
+int m_pload(WORD inst, WORD siz)
+{
+ CHECKNO30;
+ return error("Not implemented yet.");
+}
+
+//
+// pmove (68030)
+//
+int m_pmove(WORD inst, WORD siz)
+{
+ int inst2,reg;
+
+ CHECKNO30;
+
+ inst2 = inst&(1 << 8); //Copy the flush bit over to inst2 in case we're called from m_pmovefd
+ inst &= ~(1 << 8); //And mask it out
+ if (am0 == CREG)
+ {
+ reg=a0reg;
+ inst2|= (1<<9);
+ }
+ else if (am1 == CREG)
+ {
+ reg = a1reg;
+ inst2|=0;
+ }
+ else
+ return error("pmove sez: Wut?");
+
+ if ((reg == KW_URP-KW_SFC || reg == KW_SRP-KW_SFC) && ((siz != SIZD) && (siz!=SIZN)))
+ return error(siz_error);
+ if ((reg == KW_TC-KW_SFC || reg == KW_TT0-KW_SFC || reg == KW_TT1-KW_SFC) && ((siz != SIZL)&&(siz!=SIZN)))
+ return error(siz_error);
+ if ((reg == KW_MMUSR-KW_SFC) && ((siz != SIZW)&&(siz!=SIZN)))
+ return error(siz_error);
+
+ WARNING(Not all addressing modes are legal here!)
+ if (am0 == CREG)
+ {
+ inst|=am1;
+ D_word(inst);
+ ea1gen(siz);
+ }
+ else if (am1 == CREG)
+ {
+ inst|=am0;
+ D_word(inst);
+ ea0gen(siz);
+ }
+
+ switch (reg)
+ {
+ case (KW_URP-KW_SFC):
+ inst2 |= (3 << 10) + (2 << 13); break;
+ case (KW_SRP-KW_SFC):
+ inst2 |= (2 << 10) + (2 << 13); break;
+ case (KW_TC-KW_SFC):
+ inst2 |= (0 << 10) + (2 << 13); break;
+ case (KW_TT0-KW_SFC):
+ inst2 |= (2 << 10) + (0 << 13); break;
+ case (KW_TT1-KW_SFC):
+ inst2 |= (3 << 10) + (0 << 13); break;
+ case (KW_MMUSR-KW_SFC):
+ inst2 |= (3 << 10) + (3 << 13); break;
+ case (KW_CRP-KW_SFC) : //68851 only
+ inst2 |= (3 << 10) + (2 << 13); break;
+ }
+
+ D_word(inst2);
+
+ return OK;
+}
+
+//
+// pmovefd (68030)
+//
+int m_pmovefd(WORD inst, WORD siz)
+{
+ CHECKNO30;
+
+ return m_pmove(inst|(1<<8),siz);
+}
+
+//
+// ptrapcc (68851)
+//
+int m_ptrapbs(WORD inst, WORD siz) { CHECKNO20; if (siz == SIZW) { D_word(inst); D_word(B8(00000000)); D_word(a0exval); } else { inst |= 3; D_word(inst); D_word(B8(00000000)); D_long(a0exval); } return OK; }
+int m_ptrapbc(WORD inst, WORD siz) { CHECKNO20; if (siz == SIZW) { D_word(inst); D_word(B8(00000001)); D_word(a0exval); } else { inst |= 3; D_word(inst); D_word(B8(00000001)); D_long(a0exval); } return OK; }
+int m_ptrapls(WORD inst, WORD siz) { CHECKNO20; if (siz == SIZW) { D_word(inst); D_word(B8(00000010)); D_word(a0exval); } else { inst |= 3; D_word(inst); D_word(B8(00000010)); D_long(a0exval); } return OK; }
+int m_ptraplc(WORD inst, WORD siz) { CHECKNO20; if (siz == SIZW) { D_word(inst); D_word(B8(00000011)); D_word(a0exval); } else { inst |= 3; D_word(inst); D_word(B8(00000011)); D_long(a0exval); } return OK; }
+int m_ptrapss(WORD inst, WORD siz) { CHECKNO20; if (siz == SIZW) { D_word(inst); D_word(B8(00000100)); D_word(a0exval); } else { inst |= 3; D_word(inst); D_word(B8(00000100)); D_long(a0exval); } return OK; }
+int m_ptrapsc(WORD inst, WORD siz) { CHECKNO20; if (siz == SIZW) { D_word(inst); D_word(B8(00000101)); D_word(a0exval); } else { inst |= 3; D_word(inst); D_word(B8(00000101)); D_long(a0exval); } return OK; }
+int m_ptrapas(WORD inst, WORD siz) { CHECKNO20; if (siz == SIZW) { D_word(inst); D_word(B8(00000110)); D_word(a0exval); } else { inst |= 3; D_word(inst); D_word(B8(00000110)); D_long(a0exval); } return OK; }
+int m_ptrapac(WORD inst, WORD siz) { CHECKNO20; if (siz == SIZW) { D_word(inst); D_word(B8(00000111)); D_word(a0exval); } else { inst |= 3; D_word(inst); D_word(B8(00000111)); D_long(a0exval); } return OK; }
+int m_ptrapws(WORD inst, WORD siz) { CHECKNO20; if (siz == SIZW) { D_word(inst); D_word(B8(00001000)); D_word(a0exval); } else { inst |= 3; D_word(inst); D_word(B8(00001000)); D_long(a0exval); } return OK; }
+int m_ptrapwc(WORD inst, WORD siz) { CHECKNO20; if (siz == SIZW) { D_word(inst); D_word(B8(00001001)); D_word(a0exval); } else { inst |= 3; D_word(inst); D_word(B8(00001001)); D_long(a0exval); } return OK; }
+int m_ptrapis(WORD inst, WORD siz) { CHECKNO20; if (siz == SIZW) { D_word(inst); D_word(B8(00001010)); D_word(a0exval); } else { inst |= 3; D_word(inst); D_word(B8(00001010)); D_long(a0exval); } return OK; }
+int m_ptrapic(WORD inst, WORD siz) { CHECKNO20; if (siz == SIZW) { D_word(inst); D_word(B8(00001011)); D_word(a0exval); } else { inst |= 3; D_word(inst); D_word(B8(00001011)); D_long(a0exval); } return OK; }
+int m_ptrapgc(WORD inst, WORD siz) { CHECKNO20; if (siz == SIZW) { D_word(inst); D_word(B8(00001100)); D_word(a0exval); } else { inst |= 3; D_word(inst); D_word(B8(00001100)); D_long(a0exval); } return OK; }
+int m_ptrapgs(WORD inst, WORD siz) { CHECKNO20; if (siz == SIZW) { D_word(inst); D_word(B8(00001101)); D_word(a0exval); } else { inst |= 3; D_word(inst); D_word(B8(00001101)); D_long(a0exval); } return OK; }
+int m_ptrapcs(WORD inst, WORD siz) { CHECKNO20; if (siz == SIZW) { D_word(inst); D_word(B8(00001110)); D_word(a0exval); } else { inst |= 3; D_word(inst); D_word(B8(00001110)); D_long(a0exval); } return OK; }
+int m_ptrapcc(WORD inst, WORD siz) { CHECKNO20; if (siz == SIZW) { D_word(inst); D_word(B8(00001111)); D_word(a0exval); } else { inst |= 3; D_word(inst); D_word(B8(00001111)); D_long(a0exval); } return OK; }
+int m_ptrapbsn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000000)); return OK; }
+int m_ptrapbcn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000001)); return OK; }
+int m_ptraplsn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000010)); return OK; }
+int m_ptraplcn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000011)); return OK; }
+int m_ptrapssn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000100)); return OK; }
+int m_ptrapscn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000101)); return OK; }
+int m_ptrapasn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000110)); return OK; }
+int m_ptrapacn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000111)); return OK; }
+int m_ptrapwsn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001000)); return OK; }
+int m_ptrapwcn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001001)); return OK; }
+int m_ptrapisn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001010)); return OK; }
+int m_ptrapicn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001011)); return OK; }
+int m_ptrapgsn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001100)); return OK; }
+int m_ptrapgcn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001101)); return OK; }
+int m_ptrapcsn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001110)); return OK; }
+int m_ptrapccn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001111)); return OK; }
+
+//
+// ptestr, ptestw (68030)
+//
+int m_ptest(WORD inst, WORD siz)
+{
+ CHECKNO30;
+ if (activecpu == CPU_68030)
+ return error("Not implemented yet.");
+ else if (activecpu == CPU_68040)
+ return error("Not implemented yet.");
+ return ERROR;
+}
+
+#define FPU_NOWARN 0
+#define FPU_P_EMUL 1
+#define FPU_P2_EMU 2
+#define FPU_FPSP 4
+
+//
+// Generate a FPU opcode
+//
+static inline int gen_fpu(WORD inst, WORD siz, WORD opmode, WORD emul)
+{
+ if (am0<AM_NONE) // Check first operand for ea or fp - is this right?
+ {
+ inst|=(1<<9); // Bolt on FPU id
+ inst|=am0;
+ if (am0==DREG)
+ inst|=a0reg;
+ D_word(inst);
+ inst = 1 << 14; // R/M field (we have ea so have to set this to 1)
+ switch (siz)
+ {
+ case SIZB: inst |= (6<<10); break;
+ case SIZW: inst |= (4<<10); break;
+ case SIZL: inst |= (0<<10); break;
+ case SIZN:
+ case SIZS: inst |= (1<<10); break;
+ case SIZD: inst |= (5<<10); break;
+ case SIZX: inst |= (2<<10); break;
+ case SIZP:
+ {
+ inst |= (3<<10);
+ if (emul)
+ warn("This encoding will cause an unimplemented data type exception in the MC68040 to allow emulation in software.");
+ }
+ break;
+ default: return error("Something bad happened, possibly, in gen_fpu."); break;
+ }
+ inst |= (a1reg << 7);
+ inst |= opmode;
+ D_word(inst);
+ ea0gen(siz);
+ }
+ else
+ {
+ inst|=(1<<9); //Bolt on FPU id
+ D_word(inst);
+ inst = 0;
+ inst = a0reg << 10;
+ inst |= (a1reg << 7);
+ inst |= opmode;
+ D_word(inst);
+ }
+ if (emul&FPU_FPSP && activefpu==FPU_68040)
+ warn("Instruction is emulated in 68040");
+
+ return OK;
+}
+
+//
+// fabs, fsabs, fdabs (6888X, 68040)
+//
+int m_fabs(WORD inst, WORD siz)
+{
+ return gen_fpu(inst, siz, B8(00011000), FPU_P_EMUL);
+}
+int m_fsabs(WORD inst, WORD siz)
+{
+ if (activefpu == FPU_68040)
+ return gen_fpu(inst, siz, B8(01011000), FPU_P_EMUL);
+ else
+ return error("Unsupported in current FPU");
+}
+int m_fdabs(WORD inst, WORD siz)
+{
+ if (activefpu == FPU_68040)
+ return gen_fpu(inst, siz, B8(01011100), FPU_P_EMUL);
+ else
+ return error("Unsupported in current FPU");
+}
+
+//
+// facos (6888X, 68040FPSP)
+//
+int m_facos(WORD inst, WORD siz)
+{
+ return gen_fpu(inst, siz, B8(00011100), FPU_FPSP);
+}
+
+//
+// fadd (6888X, 68040FPSP)
+//
+int m_fadd(WORD inst, WORD siz)
+{
+ return gen_fpu(inst, siz, B8(00100010), FPU_P_EMUL);
+}
+int m_fsadd(WORD inst, WORD siz)
+{
+ if (activefpu == FPU_68040)
+ return gen_fpu(inst, siz, B8(01100010), FPU_P_EMUL);
+ else
+ return error("Unsupported in current FPU");
+}
+int m_fdadd(WORD inst, WORD siz)
+{
+ if (activefpu == FPU_68040)
+ return gen_fpu(inst, siz, B8(01100110), FPU_P_EMUL);
+ else
+ return error("Unsupported in current FPU");
+}
+
+//
+// fasin (6888X, 68040FPSP)f
+//
+int m_fasin(WORD inst, WORD siz)
+{
+ return gen_fpu(inst, siz, B8(00001100), FPU_FPSP);
+}
+
+//
+// fatan (6888X, 68040FPSP)
+//
+int m_fatan(WORD inst, WORD siz)
+{
+ return gen_fpu(inst, siz, B8(00001010), FPU_FPSP);
+}
+
+//
+// fatanh (6888X, 68040FPSP)
+//
+int m_fatanh(WORD inst, WORD siz)
+{
+ return gen_fpu(inst, siz, B8(00001101), FPU_FPSP);
+}
+
+//
+// fcmp (6888X, 68040)
+//
+int m_fcmp(WORD inst, WORD siz)
+{
+ return gen_fpu(inst, siz, B8(00111000), FPU_P_EMUL);
+}
+
+//
+// fcos (6888X, 68040FPSP)
+//
+int m_fcos(WORD inst, WORD siz)
+{
+ return gen_fpu(inst, siz, B8(00011101), FPU_FPSP);
+}
+
+//
+// fcosh (6888X, 68040FPSP)
+//
+int m_fcosh(WORD inst, WORD siz)
+{
+ return gen_fpu(inst, siz, B8(00011001), FPU_FPSP);
+}
+
+//
+// fdbcc (6888X, 68040)
+//
+int m_fdbcc(WORD inst, WORD siz)
+{
+ VALUE v;
+
+ WORD opcode=inst&0x3f; //Grab conditional bitfield
+
+ inst&=~0x3f;
+ inst|=1<<3;
+
+ siz = siz;
+ inst |= a0reg;
+ D_word(inst);
+
+ D_word(opcode);
+
+ if (a1exattr & DEFINED)
+ {
+ if ((a1exattr & TDB) != cursect)
+ return error(rel_error);
+
+ v = a1exval - sloc;
+
+ if (v + 0x8000 > 0x10000)
+ return error(range_error);
+
+ D_word(v);
+ }
+ else
+ {
+ AddFixup(FU_WORD | FU_PCREL | FU_ISBRA, sloc, a1expr);
+ D_word(0);
+ }
+
+ return OK;
+}
+
+
+
+
+//
+// fdiv (6888X, 68040)
+//
+int m_fdiv(WORD inst, WORD siz)
+{
+ return gen_fpu(inst, siz, B8(00100000), FPU_P_EMUL);
+}
+int m_fsdiv(WORD inst, WORD siz)
+{
+ if (activefpu == FPU_68040)
+ return gen_fpu(inst, siz, B8(01100000), FPU_P_EMUL);
+ else
+ return error("Unsupported in current FPU");
+}
+int m_fddiv(WORD inst, WORD siz)
+{
+ if (activefpu == FPU_68040)
+ return gen_fpu(inst, siz, B8(01100100), FPU_P_EMUL);
+ else
+ return error("Unsupported in current FPU");
+}
+
+//
+// fetox (6888X, 68040FPSP)
+//
+int m_fetox(WORD inst, WORD siz)
+{
+ return gen_fpu(inst, siz, B8(00010000), FPU_FPSP);
+}
+
+//
+// fetoxm1 (6888X, 68040FPSP)
+//
+int m_fetoxm1(WORD inst, WORD siz)
+{
+ return gen_fpu(inst, siz, B8(00001000), FPU_FPSP);
+}
+
+//
+// fgetexp (6888X, 68040FPSP)
+//
+int m_fgetexp(WORD inst, WORD siz)
+{
+ return gen_fpu(inst, siz, B8(00011110), FPU_FPSP);
+}
+
+//
+// fgetman (6888X, 68040FPSP)
+//
+int m_fgetman(WORD inst, WORD siz)
+{
+ return gen_fpu(inst, siz, B8(00011111), FPU_FPSP);
+}
+
+//
+// fint (6888X, 68040FPSP)
+//
+int m_fint(WORD inst, WORD siz)
+{
+ if (am1==AM_NONE)
+ // special case - fint fpx = fint fpx,fpx
+ a1reg=a0reg;
+ return gen_fpu(inst, siz, B8(00000001), FPU_FPSP);
+}
+
+//
+// fintrz (6888X, 68040FPSP)
+//
+int m_fintrz(WORD inst, WORD siz)
+{
+ if (am1==AM_NONE)
+ // special case - fintrz fpx = fintrz fpx,fpx
+ a1reg=a0reg;
+ return gen_fpu(inst, siz, B8(00000011), FPU_FPSP);
+}
+
+//
+// flog10 (6888X, 68040FPSP)
+//
+int m_flog10(WORD inst, WORD siz)
+{
+ return gen_fpu(inst, siz, B8(00010101), FPU_FPSP);
+}
+
+//
+// flog2 (6888X, 68040FPSP)
+//
+int m_flog2(WORD inst, WORD siz)
+{
+ return gen_fpu(inst, siz, B8(00010110), FPU_FPSP);
+}
+
+//
+// flogn (6888X, 68040FPSP)
+//
+int m_flogn(WORD inst, WORD siz)
+{
+ return gen_fpu(inst, siz, B8(00010100), FPU_FPSP);
+}
+
+//
+// flognp1 (6888X, 68040FPSP)
+//
+int m_flognp1(WORD inst, WORD siz)
+{
+ return gen_fpu(inst, siz, B8(00000110), FPU_FPSP);
+}
+
+//
+// fmod (6888X, 68040FPSP)
+//
+int m_fmod(WORD inst, WORD siz)
+{
+ return gen_fpu(inst, siz, B8(00100001), FPU_FPSP);
+}
+
+//
+// fmove (6888X, 68040)
+//
+int m_fmove(WORD inst, WORD siz)
+{
+
+ ////////////ea to register
+ if (am0==FREG&&am1<AM_USP)
+ {
+ //fpx->ea
+
+ //ea
+ inst|=am1|a1reg;
+ D_word(inst);
+
+ //r/m
+ //if (am0==DREG)
+ inst=3<<13;
+ //else
+ // inst=0;
+
+ WARNING("K-factor logic is totally bogus - fix!")
+
+ //source specifier
+ switch (siz)
+ {
+ case SIZB: inst |= (6<<10); break;
+ case SIZW: inst |= (4<<10); break;
+ case SIZL: inst |= (0<<10); break;
+ case SIZN:
+ case SIZS: inst |= (1<<10); break;
+ case SIZD: inst |= (5<<10); break;
+ case SIZX: inst |= (2<<10); break;
+ case SIZP: inst |= (3<<10); if (bfparam1) inst|=1<<12; inst|=(bfparam1&0x7ff)>>2; break;
+ default: return error("Something bad happened, possibly."); break;
+ }
+
+ //immediate {} value
+ if (bf0exval>=1<<6)
+ return error("K-factor must be between 0 and 31");
+ if ((!bfparam1) && siz==SIZP)
+ inst|=bf0exval;
+
+ //destination specifier
+ inst|=(a0reg<<7);
+
+ //opmode
+ inst|=0;
+
+ D_word(inst);
+ ea1gen(siz);
+
+ }
+ else if (am0<AM_USP&&am1==FREG)
+ {
+ //ea->fpx
+
+ //ea
+ inst|=am0|a0reg;
+ D_word(inst);
+
+ //r/m
+ //if (am0==DREG)
+ inst=1<<14;
+ //else
+ // inst=0;
+
+ //source specifier
+ switch (siz)
+ {
+ case SIZB: inst |= (6<<10); break;
+ case SIZW: inst |= (4<<10); break;
+ case SIZL: inst |= (0<<10); break;
+ case SIZN:
+ case SIZS: inst |= (1<<10); break;
+ case SIZD: inst |= (5<<10); break;
+ case SIZX: inst |= (2<<10); break;
+ case SIZP: inst |= (3<<10); break;
+ default: return error("Something bad happened, possibly."); break;
+ }
+
+ //destination specifier
+ inst|=(a1reg<<7);
+
+ //opmode
+ inst|=0;
+
+ D_word(inst);
+ ea0gen(siz);
+
+ }
+ else if (am0==FREG&&am1==FREG)
+ {
+ //ea
+ D_word(inst);
+
+ //r/m
+ inst=0<<14;
+
+ //source specifier
+ if (siz!=SIZX)
+ return error("Invalid size");
+
+ //source register
+ inst|=(a0reg<<10);
+
+ //destination register
+ inst|=(a1reg<<7);
+
+ D_word(inst);
+ }
+
+ return OK;
+ ///////////register to memory
+ //ea
+ //destination format
+ //source register
+ //k-factor (if required)
+
+
+ //return error("Not implemented yet.");
+ //return gen_fpu(inst, siz, B8(00101101), FPU_P_EMUL);
+}
+
+//
+// fmove (6888X, 68040)
+//
+int m_fmovescr(WORD inst, WORD siz)
+{
+ ///////////Move Floating-Point System Control Register (FPCR)
+ //ea
+ //dr
+ //register select
+ if (am0==FPSCR&&am1<AM_USP)
+ {
+ inst|=am1|a1reg;
+ D_word(inst);
+ inst=(1<<13)+(1<<15);
+ inst|=a0reg;
+ D_word(inst);
+ ea1gen(siz);
+ return OK;
+ }
+ else if (am1==FPSCR&&am0<AM_USP)
+ {
+ inst|=am0|a0reg;
+ D_word(inst);
+ inst=(0<<13)+(1<<15);
+ inst|=a1reg;
+ D_word(inst);
+ ea0gen(siz);
+ return OK;
+ }
+ else
+ return error("m_fmovescr says: wut?");
+}
+
+//
+// fsmove/fdmove (68040)
+//
+int m_fsmove(WORD inst, WORD siz)
+{
+ return error("Not implemented yet.");
+ if (activefpu == FPU_68040)
+ return gen_fpu(inst, siz, B8(01100100), FPU_P_EMUL);
+ else
+ return error("Unsupported in current FPU");
+}
+int m_fdmove(WORD inst, WORD siz)
+{
+ return error("Not implemented yet.");
+ if (activefpu == FPU_68040)
+ return gen_fpu(inst, siz, B8(01100100), FPU_P_EMUL);
+ else
+ return error("Unsupported in current FPU");
+}
+//
+// fmovecr (6888X, 68040FPSP)
+//
+int m_fmovecr(WORD inst, WORD siz)
+{
+ D_word(inst);
+ inst = 0x5c00;
+ inst |= a1reg << 7;
+ inst |= a0exval;
+ D_word(inst);
+ if (activefpu == FPU_68040)
+ warn("Instruction is emulated in 68040");
+ return OK;
+}
+
+//
+// fmovem (6888X, 68040)
+//
+int m_fmovem(WORD inst, WORD siz)
+{
+ WORD regmask;
+ WORD datareg;
+
+ if (siz == SIZX)
+ {
+ if (*tok>=KW_FP0 && *tok<=KW_FP7)
+ {
+ //fmovem.x <rlist>,ea
+ if (fpu_reglist_left(®mask) < 0)
+ return OK;
+ if (*tok++ != ',')
+ return error("missing comma");
+ if (amode(0) < 0)
+ return OK;
+ inst|=am0|a0reg;
+ if (!(amsktab[am0] & (C_ALTCTRL | M_APREDEC)))
+ return error("invalid addressing mode");
+ D_word(inst);
+ inst=((1<<15)|(1<<14))|(1<<13)|(0<<11)|regmask;
+ D_word(inst);
+ ea0gen(siz);
+ return OK;
+ }
+ else if (*tok >= KW_D0 && *tok <= KW_D7)
+ {
+ //fmovem.x Dn,ea
+ datareg=(*tok++&7)<<10;
+ if (*tok++ != ',')
+ return error("missing comma");
+ if (amode(0) < 0)
+ return OK;
+ inst|=am0|a0reg;
+ if (!(amsktab[am0] & (C_ALTCTRL | M_APREDEC)))
+ return error("invalid addressing mode");
+ D_word(inst);
+ inst=((1<<15)|(1<<14))|(1<<13)|(1<<11)|(datareg<<4);
+ D_word(inst);
+ ea0gen(siz);
+ return OK;
+ }
+ else
+ {
+ //fmovem.x ea,...
+ if (amode(0) < 0)
+ return OK;
+ inst|=am0|a0reg;
+ if (*tok++ != ',')
+ return error("missing comma");
+ if (*tok>=KW_FP0 && *tok<=KW_FP7)
+ {
+ //fmovem.x ea,<rlist>
+ if (fpu_reglist_right(®mask) < 0)
+ return OK;
+ D_word(inst);
+ inst=((1<<15)|(1<<14))|(0<<13)|(2<<11)|regmask;
+ D_word(inst);
+ ea0gen(siz);
+ return OK;
+ }
+ else
+ {
+ //fmovem.x ea,Dn
+ datareg=(*tok++&7)<<10;
+ D_word(inst);
+ inst=((1<<15)|(1<<14))|(0<<13)|(3<<11)|(datareg<<4);
+ D_word(inst);
+ ea0gen(siz);
+ return OK;
+ }
+ }
+ }
+ else if (siz == SIZL||siz==SIZN)
+ {
+ if (*tok==KW_FPCR || *tok==KW_FPSR || *tok==KW_FPIAR)
+ {
+ //fmovem.l <rlist>,ea
+ regmask=(1<<15)|(1<<13);
+fmovem_loop_1:
+ if (*tok==KW_FPCR)
+ {
+ regmask|=(1<<12);
+ tok++;
+ goto fmovem_loop_1;
+ }
+ if (*tok==KW_FPSR)
+ {
+ regmask|=(1<<11);
+ tok++;
+ goto fmovem_loop_1;
+ }
+ if (*tok==KW_FPIAR)
+ {
+ regmask|=(1<<10);
+ tok++;
+ goto fmovem_loop_1;
+ }
+ if (*tok=='/' || *tok=='-')
+ {
+ tok++;
+ goto fmovem_loop_1;
+ }
+ if (*tok++ != ',')
+ return error("missing comma");
+ if (amode(0) < 0)
+ return OK;
+ inst|=am0|a0reg;
+ D_word(inst);
+ D_word(regmask);
+ ea0gen(siz);
+ }
+ else
+ {
+ //fmovem.l ea,<rlist>
+ if (amode(0) < 0)
+ return OK;
+ inst|=am0|a0reg;
+ if (*tok++ != ',')
+ return error("missing comma");
+ regmask=(1<<15)|(0<<13);
+fmovem_loop_2:
+ if (*tok==KW_FPCR)
+ {
+ regmask|=(1<<12);
+ tok++;
+ goto fmovem_loop_2;
+ }
+ if (*tok==KW_FPSR)
+ {
+ regmask|=(1<<11);
+ tok++;
+ goto fmovem_loop_2;
+ }
+ if (*tok==KW_FPIAR)
+ {
+ regmask|=(1<<10);
+ tok++;
+ goto fmovem_loop_2;
+ }
+ if (*tok=='/' || *tok=='-')
+ {
+ tok++;
+ goto fmovem_loop_2;
+ }
+ if (*tok!=EOL)
+ return error("extra (unexpected) text found");
+ inst|=am0|a0reg;
+ D_word(inst);
+ D_word(regmask);
+ ea0gen(siz);
+ }
+ }
+ else
+ return error("bad size suffix");
+
+ return OK;
+}
+
+//
+// fmul (6888X, 68040)
+//
+int m_fmul(WORD inst, WORD siz)
+{
+ return gen_fpu(inst, siz, B8(00100011), FPU_P_EMUL);
+}
+int m_fsmul(WORD inst, WORD siz)
+{
+ if (activefpu == FPU_68040)
+ return gen_fpu(inst, siz, B8(01100011), FPU_P_EMUL);
+ else
+ return error("Unsupported in current FPU");
+}
+int m_fdmul(WORD inst, WORD siz)
+{
+ if (activefpu == FPU_68040)
+ return gen_fpu(inst, siz, B8(01100111), FPU_P_EMUL);
+ else
+ return error("Unsupported in current FPU");
+}
+
+//
+// fneg (6888X, 68040)
+//
+int m_fneg(WORD inst, WORD siz)
+{
+ return gen_fpu(inst, siz, B8(00011010), FPU_P_EMUL);
+}
+int m_fsneg(WORD inst, WORD siz)
+{
+ if (activefpu == FPU_68040)
+ return gen_fpu(inst, siz, B8(01011010), FPU_P_EMUL);
+ else
+ return error("Unsupported in current FPU");
+}
+int m_fdneg(WORD inst, WORD siz)
+{
+ if (activefpu == FPU_68040)
+ return gen_fpu(inst, siz, B8(01011110), FPU_P_EMUL);
+ else
+ return error("Unsupported in current FPU");
+}
+
+//
+// fnop (6888X, 68040)
+//
+int m_fnop(WORD inst, WORD siz)
+{
+ return gen_fpu(inst, siz, B8(00000000), FPU_P_EMUL);
+}
+
+//
+// frem (6888X, 68040FPSP)
+//
+int m_frem(WORD inst, WORD siz)
+{
+ return gen_fpu(inst, siz, B8(00100101), FPU_FPSP);
+}
+
+//
+// fscale (6888X, 68040FPSP)
+//
+int m_fscale(WORD inst, WORD siz)
+{
+ return gen_fpu(inst, siz, B8(00100110), FPU_FPSP);
+}
+
+//
+// FScc (6888X, 68040)
+//
+int m_fseq (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000001)); return OK;}
+int m_fsne (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001110)); return OK;}
+int m_fsgt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010010)); return OK;}
+int m_fsngt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011101)); return OK;}
+int m_fsge (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010011)); return OK;}
+int m_fsnge (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011100)); return OK;}
+int m_fslt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010100)); return OK;}
+int m_fsnlt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011011)); return OK;}
+int m_fsle (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010101)); return OK;}
+int m_fsnle (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011010)); return OK;}
+int m_fsgl (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010110)); return OK;}
+int m_fsngl (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011001)); return OK;}
+int m_fsgle (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010111)); return OK;}
+int m_fsngle(WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011000)); return OK;}
+int m_fsogt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000010)); return OK;}
+int m_fsule (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001101)); return OK;}
+int m_fsoge (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000011)); return OK;}
+int m_fsult (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001100)); return OK;}
+int m_fsolt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000100)); return OK;}
+int m_fsuge (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001011)); return OK;}
+int m_fsole (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000101)); return OK;}
+int m_fsugt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001010)); return OK;}
+int m_fsogl (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000110)); return OK;}
+int m_fsueq (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001001)); return OK;}
+int m_fsor (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000111)); return OK;}
+int m_fsun (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001000)); return OK;}
+int m_fsf (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000000)); return OK;}
+int m_fst (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001111)); return OK;}
+int m_fssf (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010000)); return OK;}
+int m_fsst (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011111)); return OK;}
+int m_fsseq (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010001)); return OK;}
+int m_fssne (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011110)); return OK;}
+
+//
+// FTRAPcc (6888X, 68040)
+//
+
+int m_ftrapeq (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00000001)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00000001)); D_long(a0exval); } return OK;}
+int m_ftrapne (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00001110)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00001110)); D_long(a0exval); } return OK;}
+int m_ftrapgt (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00010010)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00010010)); D_long(a0exval); } return OK;}
+int m_ftrapngt (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00011101)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00011101)); D_long(a0exval); } return OK;}
+int m_ftrapge (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00010011)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00010011)); D_long(a0exval); } return OK;}
+int m_ftrapnge (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00011100)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00011100)); D_long(a0exval); } return OK;}
+int m_ftraplt (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00010100)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00010100)); D_long(a0exval); } return OK;}
+int m_ftrapnlt (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00011011)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00011011)); D_long(a0exval); } return OK;}
+int m_ftraple (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00010101)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00010101)); D_long(a0exval); } return OK;}
+int m_ftrapnle (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00011010)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00011010)); D_long(a0exval); } return OK;}
+int m_ftrapgl (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00010110)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00010110)); D_long(a0exval); } return OK;}
+int m_ftrapngl (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00011001)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00011001)); D_long(a0exval); } return OK;}
+int m_ftrapgle (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00010111)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00010111)); D_long(a0exval); } return OK;}
+int m_ftrapngle(WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00011000)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00011000)); D_long(a0exval); } return OK;}
+int m_ftrapogt (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00000010)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00000010)); D_long(a0exval); } return OK;}
+int m_ftrapule (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00001101)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00001101)); D_long(a0exval); } return OK;}
+int m_ftrapoge (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00000011)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00000011)); D_long(a0exval); } return OK;}
+int m_ftrapult (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00001100)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00001100)); D_long(a0exval); } return OK;}
+int m_ftrapolt (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00000100)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00000100)); D_long(a0exval); } return OK;}
+int m_ftrapuge (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00001011)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00001011)); D_long(a0exval); } return OK;}
+int m_ftrapole (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00000101)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00000101)); D_long(a0exval); } return OK;}
+int m_ftrapugt (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00001010)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00001010)); D_long(a0exval); } return OK;}
+int m_ftrapogl (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00000110)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00000110)); D_long(a0exval); } return OK;}
+int m_ftrapueq (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00001001)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00001001)); D_long(a0exval); } return OK;}
+int m_ftrapor (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00000111)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00000111)); D_long(a0exval); } return OK;}
+int m_ftrapun (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00001000)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00001000)); D_long(a0exval); } return OK;}
+int m_ftrapf (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00000000)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00000000)); D_long(a0exval); } return OK;}
+int m_ftrapt (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00001111)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00001111)); D_long(a0exval); } return OK;}
+int m_ftrapsf (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00010000)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00010000)); D_long(a0exval); } return OK;}
+int m_ftrapst (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00011111)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00011111)); D_long(a0exval); } return OK;}
+int m_ftrapseq (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00010001)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00010001)); D_long(a0exval); } return OK;}
+int m_ftrapsne (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00011110)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00011110)); D_long(a0exval); } return OK;}
+
+int m_ftrapeqn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000001)); return OK;}
+int m_ftrapnen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001110)); return OK;}
+int m_ftrapgtn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010010)); return OK;}
+int m_ftrapngtn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011101)); return OK;}
+int m_ftrapgen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010011)); return OK;}
+int m_ftrapngen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011100)); return OK;}
+int m_ftrapltn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010100)); return OK;}
+int m_ftrapnltn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011011)); return OK;}
+int m_ftraplen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010101)); return OK;}
+int m_ftrapnlen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011010)); return OK;}
+int m_ftrapgln (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010110)); return OK;}
+int m_ftrapngln (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011001)); return OK;}
+int m_ftrapglen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010111)); return OK;}
+int m_ftrapnglen(WORD inst, WORD siz) { D_word(inst); D_word(B8(00011000)); return OK;}
+int m_ftrapogtn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000010)); return OK;}
+int m_ftrapulen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001101)); return OK;}
+int m_ftrapogen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000011)); return OK;}
+int m_ftrapultn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001100)); return OK;}
+int m_ftrapoltn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000100)); return OK;}
+int m_ftrapugen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001011)); return OK;}
+int m_ftrapolen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000101)); return OK;}
+int m_ftrapugtn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001010)); return OK;}
+int m_ftrapogln (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000110)); return OK;}
+int m_ftrapueqn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001001)); return OK;}
+int m_ftraporn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000111)); return OK;}
+int m_ftrapunn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001000)); return OK;}
+int m_ftrapfn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000000)); return OK;}
+int m_ftraptn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001111)); return OK;}
+int m_ftrapsfn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010000)); return OK;}
+int m_ftrapstn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011111)); return OK;}
+int m_ftrapseqn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010001)); return OK;}
+int m_ftrapsnen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011110)); return OK;}
+
+
+//
+// fsgldiv (6888X, 68040)
+//
+int m_fsgldiv(WORD inst, WORD siz)
+{
+ return gen_fpu(inst, siz, B8(00100100), FPU_P_EMUL);
+}
+
+//
+// fsglmul (6888X, 68040)
+//
+int m_fsglmul(WORD inst, WORD siz)
+{
+ return gen_fpu(inst, siz, B8(00100111), FPU_P_EMUL);
+}
+
+//
+// fsin (6888X, 68040FPSP)
+//
+int m_fsin(WORD inst, WORD siz)
+{
+ return gen_fpu(inst, siz, B8(00001110), FPU_FPSP);
+}
+
+//
+// fsincos (6888X, 68040FPSP)
+//
+int m_fsincos(WORD inst, WORD siz)
+{
+ int temp;
+ if (gen_fpu(inst, siz, B8(00110000), FPU_FPSP)==OK)
+ {
+ chptr[-1] |= a2reg;
+ return OK;
+ }
+ else
+ return ERROR;
+}
+
+//
+// fsin (6888X, 68040FPSP)
+//
+int m_fsinh(WORD inst, WORD siz)
+{
+ return gen_fpu(inst, siz, B8(00000010), FPU_FPSP);
+}
+
+//
+// fsqrt (6888X, 68040)
+//
+int m_fsqrt(WORD inst, WORD siz)
+{
+ return gen_fpu(inst, siz, B8(00000100), FPU_P_EMUL);
+}
+int m_fsfsqrt(WORD inst, WORD siz)
+{
+ if (activefpu == FPU_68040)
+ return gen_fpu(inst, siz, B8(01000001), FPU_P_EMUL);
+ else
+ return error("Unsupported in current FPU");
+}
+int m_fdfsqrt(WORD inst, WORD siz)
+{
+ if (activefpu == FPU_68040)
+ return gen_fpu(inst, siz, B8(01000101), FPU_P_EMUL);
+ else
+ return error("Unsupported in current FPU");
+}
+
+//
+// fsub (6888X, 68040)
+//
+int m_fsub(WORD inst, WORD siz)
+{
+ return gen_fpu(inst, siz, B8(00101000), FPU_P_EMUL);
+}
+int m_fsfsub(WORD inst, WORD siz)
+{
+ if (activefpu == FPU_68040)
+ return gen_fpu(inst, siz, B8(01101000), FPU_P_EMUL);
+ else
+ return error("Unsupported in current FPU");
+}
+int m_fdsub(WORD inst, WORD siz)
+{
+ if (activefpu == FPU_68040)
+ return gen_fpu(inst, siz, B8(01101100), FPU_P_EMUL);
+ else
+ return error("Unsupported in current FPU");
+}
+
+//
+// ftan (6888X, 68040FPSP)
+//
+int m_ftan(WORD inst, WORD siz)
+{
+ return gen_fpu(inst, siz, B8(00001111), FPU_FPSP);
+}
+
+//
+// ftanh (6888X, 68040FPSP)
+//
+int m_ftanh(WORD inst, WORD siz)
+{
+ return gen_fpu(inst, siz, B8(00001001), FPU_FPSP);
+}
+
+//
+// ftentox (6888X, 68040FPSP)
+//
+int m_ftentox(WORD inst, WORD siz)
+{
+ return gen_fpu(inst, siz, B8(00010010), FPU_FPSP);
+}
+
+//
+// ftst (6888X, 68040)
+//
+int m_ftst(WORD inst, WORD siz)
+{
+ return gen_fpu(inst, siz, B8(00111010), FPU_P_EMUL);
+}
+
+//
+// ftwotox (6888X, 68040FPSP)
+//
+int m_ftwotox(WORD inst, WORD siz)
+{
+ return gen_fpu(inst, siz, B8(00010001), FPU_FPSP);
}
#ifndef __MACH_H__
#define __MACH_H__
+#include "rmac.h"
#include "amode.h"
// Exported variables
extern char range_error[];
extern char abs_error[];
extern MNTAB machtab[];
+extern int activecpu;
+extern int activefpu;
extern int movep;
+// Fucntion prototypes
+int m_unimp(WORD, WORD), m_badmode(WORD, WORD), m_bad6mode(WORD, WORD), m_bad6inst(WORD, WORD);
+int m_self(WORD, WORD);
+int m_abcd(WORD, WORD);
+int m_reg(WORD, WORD);
+int m_imm(WORD, WORD);
+int m_imm8(WORD, WORD);
+int m_shi(WORD, WORD);
+int m_shr(WORD, WORD);
+int m_bitop(WORD, WORD);
+int m_exg(WORD, WORD);
+int m_ea(WORD, WORD);
+int m_lea(WORD, WORD);
+int m_br(WORD, WORD);
+int m_dbra(WORD, WORD);
+int m_link(WORD, WORD);
+int m_adda(WORD, WORD);
+int m_addq(WORD, WORD);
+//int m_move(WORD, int);
+int m_move(WORD, WORD);
+int m_moveq(WORD, WORD);
+int m_usp(WORD, WORD);
+int m_movep(WORD, WORD);
+int m_trap(WORD, WORD);
+int m_movem(WORD, WORD);
+int m_clra(WORD, WORD);
+
+int m_move30(WORD, WORD); //68020/30/40/60
+int m_br30(WORD inst, WORD siz);
+int m_ea030(WORD inst, WORD siz);
+int m_bfop(WORD inst, WORD siz);
+int m_callm(WORD inst, WORD siz);
+int m_cas(WORD inst, WORD siz);
+int m_cas2(WORD inst, WORD siz);
+int m_chk2(WORD inst, WORD siz);
+int m_cmp2(WORD inst, WORD siz);
+int m_bkpt(WORD inst, WORD siz);
+int m_cpbr(WORD inst, WORD siz);
+int m_cpdbr(WORD inst, WORD siz);
+int m_divs(WORD inst, WORD siz);
+int m_muls(WORD inst, WORD siz);
+int m_divu(WORD inst, WORD siz);
+int m_mulu(WORD inst, WORD siz);
+int m_divsl(WORD inst, WORD siz);
+int m_divul(WORD inst, WORD siz);
+int m_move16a(WORD inst, WORD siz);
+int m_move16b(WORD inst, WORD siz);
+int m_pack(WORD inst, WORD siz);
+int m_rtm(WORD inst, WORD siz);
+int m_rtd(WORD inst, WORD siz);
+int m_trapcc(WORD inst, WORD siz);
+int m_cinv(WORD inst, WORD siz);
+int m_cprest(WORD inst, WORD siz);
+int m_movec(WORD inst, WORD siz);
+int m_moves(WORD inst, WORD siz);
+
+// PMMU
+int m_pbcc(WORD inst, WORD siz);
+int m_pflusha(WORD inst, WORD siz);
+int m_pflush(WORD inst, WORD siz);
+int m_pflushr(WORD inst, WORD siz);
+int m_pload(WORD inst, WORD siz);
+int m_pmove(WORD inst, WORD siz);
+int m_pmovefd(WORD inst, WORD siz);
+int m_ptest(WORD inst, WORD siz);
+int m_ptrapbs(WORD inst, WORD siz);
+int m_ptrapbc(WORD inst, WORD siz);
+int m_ptrapls(WORD inst, WORD siz);
+int m_ptraplc(WORD inst, WORD siz);
+int m_ptrapss(WORD inst, WORD siz);
+int m_ptrapsc(WORD inst, WORD siz);
+int m_ptrapas(WORD inst, WORD siz);
+int m_ptrapac(WORD inst, WORD siz);
+int m_ptrapws(WORD inst, WORD siz);
+int m_ptrapwc(WORD inst, WORD siz);
+int m_ptrapis(WORD inst, WORD siz);
+int m_ptrapic(WORD inst, WORD siz);
+int m_ptrapgc(WORD inst, WORD siz);
+int m_ptrapgs(WORD inst, WORD siz);
+int m_ptrapcs(WORD inst, WORD siz);
+int m_ptrapcc(WORD inst, WORD siz);
+int m_ptrapbsn(WORD inst, WORD siz);
+int m_ptrapbcn(WORD inst, WORD siz);
+int m_ptraplsn(WORD inst, WORD siz);
+int m_ptraplcn(WORD inst, WORD siz);
+int m_ptrapssn(WORD inst, WORD siz);
+int m_ptrapscn(WORD inst, WORD siz);
+int m_ptrapasn(WORD inst, WORD siz);
+int m_ptrapacn(WORD inst, WORD siz);
+int m_ptrapwsn(WORD inst, WORD siz);
+int m_ptrapwcn(WORD inst, WORD siz);
+int m_ptrapisn(WORD inst, WORD siz);
+int m_ptrapicn(WORD inst, WORD siz);
+int m_ptrapgsn(WORD inst, WORD siz);
+int m_ptrapgcn(WORD inst, WORD siz);
+int m_ptrapcsn(WORD inst, WORD siz);
+int m_ptrapccn(WORD inst, WORD siz);
+
+//FPU
+int m_fabs(WORD inst, WORD siz);
+int m_facos(WORD inst, WORD siz);
+int m_fadd(WORD inst, WORD siz);
+int m_fasin(WORD inst, WORD siz);
+int m_fatan(WORD inst, WORD siz);
+int m_fatanh(WORD inst, WORD siz);
+int m_fcmp(WORD inst, WORD siz);
+int m_fcos(WORD inst, WORD siz);
+int m_fcosh(WORD inst, WORD siz);
+int m_fdabs(WORD inst, WORD siz);
+int m_fdadd(WORD inst, WORD siz);
+int m_fdbcc(WORD inst, WORD siz);
+int m_fddiv(WORD inst, WORD siz);
+int m_fdfsqrt(WORD inst, WORD siz);
+int m_fdiv(WORD inst, WORD siz);
+int m_fdmove(WORD inst, WORD siz);
+int m_fdmul(WORD inst, WORD siz);
+int m_fdneg(WORD inst, WORD siz);
+int m_fdsub(WORD inst, WORD siz);
+int m_fetox(WORD inst, WORD siz);
+int m_fetoxm1(WORD inst, WORD siz);
+int m_fgetexp(WORD inst, WORD siz);
+int m_fgetman(WORD inst, WORD siz);
+int m_fint(WORD inst, WORD siz);
+int m_fintrz(WORD inst, WORD siz);
+int m_flog10(WORD inst, WORD siz);
+int m_flog2(WORD inst, WORD siz);
+int m_flogn(WORD inst, WORD siz);
+int m_flognp1(WORD inst, WORD siz);
+int m_fmod(WORD inst, WORD siz);
+int m_fmove(WORD inst, WORD siz);
+int m_fmovescr(WORD inst, WORD siz);
+int m_fmovecr(WORD inst, WORD siz);
+int m_fmovem(WORD inst, WORD siz);
+int m_fmul(WORD inst, WORD siz);
+int m_fneg(WORD inst, WORD siz);
+int m_fnop(WORD inst, WORD siz);
+int m_frem(WORD inst, WORD siz);
+int m_fsabs(WORD inst, WORD siz);
+int m_fsadd(WORD inst, WORD siz);
+int m_fseq(WORD inst, WORD siz);
+int m_fsne(WORD inst, WORD siz);
+int m_fsgt(WORD inst, WORD siz);
+int m_fsngt(WORD inst, WORD siz);
+int m_fsge(WORD inst, WORD siz);
+int m_fsnge(WORD inst, WORD siz);
+int m_fslt(WORD inst, WORD siz);
+int m_fsnlt(WORD inst, WORD siz);
+int m_fsle(WORD inst, WORD siz);
+int m_fsnle(WORD inst, WORD siz);
+int m_fsgl(WORD inst, WORD siz);
+int m_fsngl(WORD inst, WORD siz);
+int m_fsgle(WORD inst, WORD siz);
+int m_fsngle(WORD inst, WORD siz);
+int m_fsogt(WORD inst, WORD siz);
+int m_fsule(WORD inst, WORD siz);
+int m_fsoge(WORD inst, WORD siz);
+int m_fsult(WORD inst, WORD siz);
+int m_fsolt(WORD inst, WORD siz);
+int m_fsuge(WORD inst, WORD siz);
+int m_fsole(WORD inst, WORD siz);
+int m_fsugt(WORD inst, WORD siz);
+int m_fsogl(WORD inst, WORD siz);
+int m_fsueq(WORD inst, WORD siz);
+int m_fsor(WORD inst, WORD siz);
+int m_fsun(WORD inst, WORD siz);
+int m_fsf(WORD inst, WORD siz);
+int m_fst(WORD inst, WORD siz);
+int m_fssf(WORD inst, WORD siz);
+int m_fsst(WORD inst, WORD siz);
+int m_fsseq(WORD inst, WORD siz);
+int m_fssne(WORD inst, WORD siz);
+int m_fscale(WORD inst, WORD siz);
+int m_fsdiv(WORD inst, WORD siz);
+int m_fsfsqrt(WORD inst, WORD siz);
+int m_fsfsub(WORD inst, WORD siz);
+int m_fsgldiv(WORD inst, WORD siz);
+int m_fsglmul(WORD inst, WORD siz);
+int m_fsin(WORD inst, WORD siz);
+int m_fsincos(WORD inst, WORD siz);
+int m_fsinh(WORD inst, WORD siz);
+int m_fsmove(WORD inst, WORD siz);
+int m_fsmul(WORD inst, WORD siz);
+int m_fsneg(WORD inst, WORD siz);
+int m_fsqrt(WORD inst, WORD siz);
+int m_fsub(WORD inst, WORD siz);
+int m_ftan(WORD inst, WORD siz);
+int m_ftanh(WORD inst, WORD siz);
+int m_ftentox(WORD inst, WORD siz);
+int m_ftst(WORD inst, WORD siz);
+int m_ftwotox(WORD inst, WORD siz);
+int m_ftrapeq(WORD inst, WORD siz);
+int m_ftrapne(WORD inst, WORD siz);
+int m_ftrapgt(WORD inst, WORD siz);
+int m_ftrapngt(WORD inst, WORD siz);
+int m_ftrapge(WORD inst, WORD siz);
+int m_ftrapnge(WORD inst, WORD siz);
+int m_ftraplt(WORD inst, WORD siz);
+int m_ftrapnlt(WORD inst, WORD siz);
+int m_ftraple(WORD inst, WORD siz);
+int m_ftrapnle(WORD inst, WORD siz);
+int m_ftrapgl(WORD inst, WORD siz);
+int m_ftrapngl(WORD inst, WORD siz);
+int m_ftrapgle(WORD inst, WORD siz);
+int m_ftrapngle(WORD inst, WORD siz);
+int m_ftrapogt(WORD inst, WORD siz);
+int m_ftrapule(WORD inst, WORD siz);
+int m_ftrapoge(WORD inst, WORD siz);
+int m_ftrapult(WORD inst, WORD siz);
+int m_ftrapolt(WORD inst, WORD siz);
+int m_ftrapuge(WORD inst, WORD siz);
+int m_ftrapole(WORD inst, WORD siz);
+int m_ftrapugt(WORD inst, WORD siz);
+int m_ftrapogl(WORD inst, WORD siz);
+int m_ftrapueq(WORD inst, WORD siz);
+int m_ftrapor(WORD inst, WORD siz);
+int m_ftrapun(WORD inst, WORD siz);
+int m_ftrapf(WORD inst, WORD siz);
+int m_ftrapt(WORD inst, WORD siz);
+int m_ftrapsf(WORD inst, WORD siz);
+int m_ftrapst(WORD inst, WORD siz);
+int m_ftrapseq(WORD inst, WORD siz);
+int m_ftrapsne(WORD inst, WORD siz);
+int m_ftrapeqn(WORD inst, WORD siz);
+int m_ftrapnen(WORD inst, WORD siz);
+int m_ftrapgtn(WORD inst, WORD siz);
+int m_ftrapngtn(WORD inst, WORD siz);
+int m_ftrapgen(WORD inst, WORD siz);
+int m_ftrapngen(WORD inst, WORD siz);
+int m_ftrapltn(WORD inst, WORD siz);
+int m_ftrapnltn(WORD inst, WORD siz);
+int m_ftraplen(WORD inst, WORD siz);
+int m_ftrapnlen(WORD inst, WORD siz);
+int m_ftrapgln(WORD inst, WORD siz);
+int m_ftrapngln(WORD inst, WORD siz);
+int m_ftrapglen(WORD inst, WORD siz);
+int m_ftrapnglen(WORD inst, WORD siz);
+int m_ftrapogtn(WORD inst, WORD siz);
+int m_ftrapulen(WORD inst, WORD siz);
+int m_ftrapogen(WORD inst, WORD siz);
+int m_ftrapultn(WORD inst, WORD siz);
+int m_ftrapoltn(WORD inst, WORD siz);
+int m_ftrapugen(WORD inst, WORD siz);
+int m_ftrapolen(WORD inst, WORD siz);
+int m_ftrapugtn(WORD inst, WORD siz);
+int m_ftrapogln(WORD inst, WORD siz);
+int m_ftrapueqn(WORD inst, WORD siz);
+int m_ftraporn(WORD inst, WORD siz);
+int m_ftrapunn(WORD inst, WORD siz);
+int m_ftrapfn(WORD inst, WORD siz);
+int m_ftraptn(WORD inst, WORD siz);
+int m_ftrapsfn(WORD inst, WORD siz);
+int m_ftrapstn(WORD inst, WORD siz);
+int m_ftrapseqn(WORD inst, WORD siz);
+int m_ftrapsnen(WORD inst, WORD siz);
+
#endif // __MACH_H__
# Build everything
#
-all : mntab.h 68ktab.h kwtab.h risckw.h 6502.h rmac
+all : mntab.h 68ktab.h kwtab.h risckw.h 6502kw.h rmac
@echo
@echo "Don't forget to bump the version number before commiting!"
@echo
68ktab.h 68kmn : 68ktab 68ktab 68kgen
./68kgen 68kmn <68ktab >68ktab.h
+
kwtab.h : kwtab kwgen
./kwgen kw <kwtab >kwtab.h
-6502.h : 6502.tbl kwgen
+6502kw.h : 6502.tbl kwgen
./kwgen mp <6502.tbl >6502kw.h
risckw.h : kwtab kwgen
//
if (prg_flag)
{
- if ((flags & MLONG) == 0)
- error("illegal word relocatable (in .PRG mode)");
+ //if ((flags & MLONG) == 0)
+ // error("illegal word relocatable (in .PRG mode)");
if (symbol != NULL)
errors("illegal external reference (in .PRG mode) to '%s'",
gpumain 56
.prgflags 57
prgflags 57
-opt 58
-.opt 58
+.68020 58
+.68030 59
+.68040 60
+.68060 61
+.68881 62
+.68882 63
+.56001 64
+.nofpu 65
+nofpu 65
+.opt 66
+opt 66
+
.if 500
if 500
.else 501
else 501
+.endc 502
+endc 502
.endif 502
endif 502
.iif 503
endr 507
.exitm 510
exitm 510
-abcd 1001
-add 1003
-adda 1005
-addi 1006
-addq 1007
-addx 1008
-and 1010
-andi 1012
-asl 1015
-asr 1019
-bcc 1023
-bhs 1023
-bcs 1024
-blo 1024
-beq 1025
-bz 1025
-bze 1025
-bge 1026
-bgt 1027
-bhi 1028
-ble 1029
-bls 1030
-blt 1031
-bmi 1032
-bne 1033
-bnz 1033
-bpl 1034
-bvc 1035
-bvs 1036
-bchg 1037
-bclr 1041
-bra 1045
-bt 1045
-bset 1046
-bsr 1050
-btst 1051
-chk 1055
-clr 1056
-cmp 1058
-cmpa 1060
-cmpi 1061
-cmpm 1062
-dbcc 1063
-dbcs 1064
-dblo 1064
-dbeq 1065
-dbze 1065
-dbf 1066
-dbra 1066
-dbge 1067
-dbgt 1068
-dbhi 1069
-dbhs 1069
-dble 1070
-dbls 1071
-dblt 1072
-dbmi 1073
-dbne 1074
-dbnz 1074
-dbpl 1075
-dbt 1076
-dbvc 1077
-dbvs 1078
-divs 1079
-divu 1080
-eor 1081
-eori 1082
-exg 1085
-ext 1086
-illegal 1088
-jmp 1089
-jsr 1090
-lea 1091
-link 1092
-lsl 1093
-lsr 1097
-move 1101
-movea 1108
-movem 1109
-movep 1110
-moveq 1112
-muls 1113
-mulu 1114
-nbcd 1115
-neg 1116
-negx 1117
-nop 1118
-not 1119
-or 1120
-ori 1122
-pea 1125
-reset 1126
-rol 1127
-ror 1131
-roxl 1135
-roxr 1139
-rte 1143
-rtr 1144
-rts 1145
-sbcd 1146
-scc 1148
-shs 1148
-scs 1149
-slo 1149
-seq 1150
-sze 1150
-sf 1151
-sge 1152
-sgt 1153
-shi 1154
-sle 1155
-sls 1156
-slt 1157
-smi 1158
-sne 1159
-snz 1159
-spl 1160
-st 1161
-svc 1162
-svs 1163
-stop 1164
-sub 1165
-suba 1167
-subi 1168
-subq 1169
-subx 1170
-swap 1172
-tas 1173
-trap 1174
-trapv 1175
-tst 1176
-unlk 1177
AMn = AINDEXED;
goto AMn_IX0; // Handle ",Xn[.siz][*scale])"
}
+ else if ((*tok >= KW_D0) && (*tok <= KW_D7))
+ {
+ //Since index register isn't used here, store register number in this field
+ AnIXREG = *tok++ & 7; // (Dn)
+ if (*tok==')')
+ {
+ tok++;
+ AnEXTEN |= EXT_FULLWORD; // Definitely using full extension format, so set bit 8
+ AnEXTEN |= EXT_BS; // Base register suppressed
+ AnEXTEN |= EXT_BDSIZE0; // Base displacement null
+ AnEXTEN |= EXT_IISPOSN; // Indirect Postindexed with Null Outer Displacement
+ AMn= MEMPOST;
+ AnREG = 6 << 3; // stuff 110 to mode field
+ goto AnOK;
+ }
+ else if (*tok=='L')
+ {
+ // TODO: does DINDL gets used at all?
+ //AMn=DINDL; // (Dn.l)
+ //AnEXTEN = 1 << 1; // Long index size
+ //tok++;
+ }
+ else if (*tok=='W') // (Dn.w)
+ {
+ // TODO: does DINDW gets used at all?
+ //AMn=DINDW;
+ //AnEXTEN = 1 << 1; // Word index size
+ //tok++;
+ }
+ else if (*tok == ',')
+ {
+ // ([bd,An],Xn..) without bd, An
+ // Base displacement is suppressed
+ AnEXTEN |= EXT_FULLWORD; // Definitely using full extension format, so set bit 8
+ AnEXTEN |= EXT_BS; // Base register suppressed
+ AnEXTEN |= EXT_BDSIZE0;
+ AnREG = 6 << 3; // stuff 110 to mode field
+ tok++;
+ goto CHECKODn;
+ }
+ else
+ return error("(Dn) error");
+
+ if (*tok == ')')
+ {
+ tok++;
+ AnEXTEN |= EXT_FULLWORD; // Definitely using full extension format, so set bit 8
+ AnEXTEN |= EXT_BS; // Base register suppressed
+ AnEXTEN |= EXT_BDSIZE0; // Base displacement null
+ AnEXTEN |= EXT_IISPOSN; // Indirect Postindexed with Null Outer Displacement
+ AnREG = 6 << 3; // stuff 110 to mode field
+ AMn = MEMPOST;
+ goto AnOK;
+ }
+ else
+ return error("unhandled so far");
+ }
else if (*tok == KW_PC)
{ // (PC,Xn[.siz][*scale])
tok++;
}
else if (*tok == '[')
{ // ([...
- goto unmode;
+ tok++;
+ AnEXTEN|=EXT_FULLWORD; //Definitely using full extension format, so set bit 8
+ // Check to see if base displacement is present
+ //WARNING("expr will return a bad expression error here but this is expected, it needs to be silenced!");
+ if (*tok!=CONST && *tok !=SYMBOL)
+ //if (expr(AnBEXPR, &AnBEXVAL, &AnBEXATTR, &AnESYM) != OK)
+ {
+ AnEXTEN|=EXT_BDSIZE0;
+ //tok++;
+ //tok--; //Rewind tok since expr advances it forward
+ }
+ else
+ {
+ expr(AnBEXPR, &AnBEXVAL, &AnBEXATTR, &AnESYM);
+ if (optim_flags[OPT_BASE_DISP] && AnBEXVAL==0 && AnEXATTR!=0)
+ {
+ // bd=0 so let's optimise it out
+ AnEXTEN|=EXT_BDSIZE0;
+ }
+ else if (*tok==DOTL)
+ { // ([bd.l,...
+ AnEXTEN|=EXT_BDSIZEL;
+ tok++;
+ }
+ else
+ { // ([bd[.w],... or ([bd,...
+ // Is .W forced here?
+ if (*tok == DOTW)
+ {
+ AnEXTEN|=EXT_BDSIZEW;
+ tok++;
+ }
+ else
+ {
+ // Defined, absolute values from $FFFF8000..$00007FFF get optimized
+ // to absolute short
+ if (optim_flags[OPT_ABS_SHORT] && (AnBEXATTR & (TDB|DEFINED)) == DEFINED && (AnBEXVAL + 0x8000) < 0x10000)
+ {
+ AnEXTEN|=EXT_BDSIZEW;
+ warn("absolute value in base displacement ranging $FFFF8000..$00007FFF optimised to absolute short");
+ }
+ else
+ {
+ AnEXTEN|=EXT_BDSIZEL;
+ }
+ }
+ }
+ if (*tok==',')
+ tok++;
+ //else
+ // return error("Comma expected after base displacement");
+ }
+
+
+ // Check for address register or PC, suppress base register otherwise
+
+ if (*tok==KW_PC)
+ { // ([bd,PC,...
+ AnREG=(7<<3)|3; // PC is special case - stuff 011 to register field and 111 to the mode field
+ tok++;
+ }
+ else if ((*tok >= KW_A0) && (*tok <= KW_A7))
+ { // ([bd,An,...
+ AnREG = (6<<3)|*tok & 7;
+ tok++;
+ }
+ else if ((*tok >= KW_D0) && (*tok <= KW_D7))
+ { // ([bd,Dn,...
+ AnREG = (6<<3);
+ AnEXTEN|=((*tok&7)<<12);
+ AnEXTEN|=EXT_D;
+ AnEXTEN|=EXT_BS; // Oh look, a data register! Which means that base register is suppressed
+ tok++;
+
+ // Check for size
+ { // ([bd,An/PC],Xn.W/L...)
+ switch ((int)*tok)
+ { // Index reg size: <empty> | .W | .L
+ case DOTW:
+ tok++;
+ break;
+ default:
+ break;
+ case DOTL:
+ AnEXTEN |= EXT_L;
+ tok++;
+ break;
+ case DOTB: // .B not allowed here...
+ goto badmode;
+ }
+ }
+
+ // Check for scale
+ if (*tok=='*') // ([bd,An/PC],Xn*...)
+ {
+ tok++;
+ if (*tok==CONST) // TODO: I suppose the scale is stored as a CONST and nothing else? So prolly the if is not needed?
+ tok++;
+ switch ((int)*tok++)
+ {
+ case 1:
+ break;
+ case 2:
+ AnEXTEN |= EXT_TIMES2;
+ break;
+ case 4:
+ AnEXTEN |= EXT_TIMES4;
+ break;
+ case 8:
+ AnEXTEN |= EXT_TIMES8;
+ break;
+ default:
+ goto badmode;
+ }
+ }
+ if (*tok==']') // ([bd,Dn]...
+ {
+ tok++;
+ goto IS_SUPPRESSEDn;
+ }
+ }
+ else if (*tok==']')
+ {
+ // PC and Xn is suppressed
+ AnREG=6<<3; // stuff 110 to mode field
+ //AnEXTEN|=EXT_BS|EXT_IS;
+ AnEXTEN |= EXT_BS;
+ }
+ else
+ {
+ goto badmode;
+ }
+
+ // At a crossroads here. We can accept either ([bd,An/PC],... or ([bd,An/PC,Xn*scale],...
+ if (*tok==']')
+ { //([bd,An/PC],Xn,od)
+ // Check for Xn
+ tok++;
+ if (*tok==')')
+ { //Xn and od are non existent, get out of jail free card
+ AMn=MEMPRE; // ([bc,An,Xn],od) with no Xn and od
+ AnEXTEN|=EXT_IS|EXT_IISPREN; //Suppress Xn and od
+ tok++;
+ goto AnOK;
+ }
+ else if (*tok!=',')
+ return error("comma expected after ]");
+ else
+ tok++; // eat the comma
+
+ if ((*tok >= KW_A0) && (*tok <= KW_A7))
+ {
+ AnIXREG=((*tok&7)<<12);
+ AnEXTEN|=EXT_A;
+ tok++;
+ }
+ else if ((*tok >= KW_D0) && (*tok <= KW_D7))
+ {
+ AnEXTEN|=((*tok&7)<<12);
+ AnEXTEN|=EXT_D;
+ tok++;
+ }
+ else
+ {
+ //No index found, suppress it
+ AnEXTEN|=EXT_IS;
+ tok--; // Rewind tok to point to the comma
+ goto IS_SUPPRESSEDn; // https://xkcd.com/292/ - what does he know anyway?
+ }
+
+ // Check for size
+ { // ([bd,An/PC],Xn.W/L...)
+ switch ((int)*tok)
+ { // Index reg size: <empty> | .W | .L
+ case DOTW:
+ tok++;
+ break;
+ default:
+ break;
+ case DOTL:
+ AnEXTEN |= EXT_L;
+ tok++;
+ break;
+ case DOTB: // .B not allowed here...
+ goto badmode;
+ }
+ }
+
+ // Check for scale
+ if (*tok=='*') // ([bd,An/PC],Xn*...)
+ {
+ tok++;
+ if (*tok==CONST) // TODO: I suppose the scale is stored as a CONST and nothing else? So prolly the if is not needed?
+ tok++;
+ switch ((int)*tok++)
+ {
+ case 1:
+ break;
+ case 2:
+ AnEXTEN |= EXT_TIMES2;
+ break;
+ case 4:
+ AnEXTEN |= EXT_TIMES4;
+ break;
+ case 8:
+ AnEXTEN |= EXT_TIMES8;
+ break;
+ default:
+ goto badmode;
+ }
+ }
+
+ // Check for od
+ if (*tok==')') // ([bd,An/PC],Xn)
+ { //od is non existant, get out of jail free card
+ AMn=MEMPOST; // let's say it's ([bd,An],Xn,od) with od=0 then
+ AnEXTEN|=EXT_IISPOSN; // No outer displacement
+ tok++;
+ goto AnOK;
+ }
+ else if (*tok!=',')
+ return error("comma expected");
+ else
+ tok++; // eat the comma
+
+ CHECKODn:
+ if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
+ goto badmode;
+ if (optim_flags[OPT_BASE_DISP] && AnEXVAL==0)
+ {
+ // od=0 so optimise it out
+ AMn=MEMPOST; // let's say it's ([bd,An],Xn,od) with od=0 then
+ AnEXTEN|=EXT_IISPOSN; // No outer displacement
+ tok++;
+ goto AnOK;
+ }
+ // ([bd,An/PC],Xn,od)
+ if (*tok == DOTL)
+ {
+ // expr.L
+ AnEXTEN|=EXT_IISPOSL; // Long outer displacement
+ AMn = MEMPOST;
+
+ // Defined, absolute values from $FFFF8000..$00007FFF get optimized
+ // to absolute short
+ if (optim_flags[OPT_ABS_SHORT] && (AnEXATTR & (TDB|DEFINED)) == DEFINED && (AnEXVAL + 0x8000) < 0x10000)
+ {
+ AnEXTEN|=EXT_IISPOSW; // Word outer displacement
+ AMn = MEMPOST;
+ warn("outer displacement absolute value from $FFFF8000..$00007FFF optimised to absolute short");
+ }
+
+ }
+ else
+ {
+ // expr[.W]
+ AnEXTEN|=EXT_IISPOSW; // Word outer displacement
+ AMn = MEMPOST;
+
+ // Is .W forced here?
+ if (*tok == DOTW)
+ {
+ tok++;
+ }
+
+ }
+
+ // Check for final closing parenthesis
+ if (*tok==')')
+ {
+ tok++;
+ goto AnOK;
+ }
+ else
+ return error("Closing parenthesis missing on addressing mode");
+
+ IS_SUPPRESSEDn:
+
+ // Check for od
+ if (*tok==')') // ([bd,An/PC],Xn)
+ { //od is non existant, get out of jail free card
+ AMn=MEMPOST; // let's say it's ([bd,An],Xn,od) with od=0 then
+ AnEXTEN|=EXT_IISNOIN; // No outer displacement
+ tok++;
+ goto AnOK;
+ }
+ else if (*tok!=',')
+ return error("comma expected");
+ else
+ tok++; // eat the comma
+
+ if (*tok != CONST && *tok != SYMBOL)
+ //if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
+ goto badmode;
+ expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM);
+ if (optim_flags[OPT_BASE_DISP] && AnEXVAL==0)
+ {
+ // od=0 so optimise it out
+ AMn=MEMPOST; // let's say it's ([bd,An],Xn,od) with od=0 then
+ AnEXTEN|=EXT_IISNOIN; // No outer displacement
+ tok++;
+ goto AnOK;
+ }
+ // ([bd,An/PC],Xn,od)
+ if (*tok == DOTL)
+ {
+ // expr.L
+ tok++;
+ AMn = MEMPOST;
+ AnEXTEN|=EXT_IISNOIL; // Long outer displacement with IS suppressed
+ //goto AnOK;
+
+ }
+ else
+ {
+ // expr[.W][]
+ AnEXTEN |= EXT_IISNOIW; // Word outer displacement with IS suppressed
+ AMn = MEMPRE;
+ if (*tok == DOTW)
+ {
+ //AnEXTEN|=EXT_IISNOIW; // Word outer displacement
+ AMn = MEMPOST;
+ tok++;
+ }
+
+ // Defined, absolute values from $FFFF8000..$00007FFF get optimized
+ // to absolute short
+ else if (optim_flags[OPT_BASE_DISP] && (AnEXATTR & (TDB|DEFINED)) == DEFINED && (AnEXVAL + 0x8000) < 0x10000)
+ {
+ //AnEXTEN|=EXT_IISNOIW; // Word outer displacement with IS suppressed
+ warn("outer displacement absolute value from $FFFF8000..$00007FFF optimised to absolute short");
+ }
+
+
+ }
+
+ // Check for final closing parenthesis
+ if (*tok==')')
+ {
+ tok++;
+ goto AnOK;
+ }
+ else
+ return error("Closing parenthesis missing on addressing mode");
+
+ }
+ else if (*tok==',')
+ {
+ *tok++; // ([bd,An,Xn.size*scale],od)
+ //Check for Xn
+ if ((*tok >= KW_A0) && (*tok <= KW_A7))
+ {
+ AnEXTEN|=((*tok&7)<<12);
+ AnEXTEN|=EXT_A;
+ tok++;
+ }
+ else if ((*tok >= KW_D0) && (*tok <= KW_D7))
+ {
+ AnEXTEN|=((*tok&7)<<12);
+ AnEXTEN|=EXT_D;
+ tok++;
+ }
+
+ // Check for size
+ { // ([bd,An/PC],Xn.W/L...)
+ switch ((int)*tok)
+ { // Index reg size: <empty> | .W | .L
+ case DOTW:
+ tok++;
+ break;
+ default:
+ break;
+ case DOTL:
+ tok++;
+ AnEXTEN |= EXT_L;
+ break;
+ case DOTB: // .B not allowed here...
+ goto badmode;
+ }
+
+ }
+
+ // Check for scale
+ if (*tok=='*') // ([bd,An/PC],Xn*...)
+ {
+ tok++;
+ if (*tok==CONST) // TODO: I suppose the scale is stored as a CONST and nothing else? So prolly the if is not needed?
+ tok++;
+ switch ((int)*tok++)
+ {
+ case 1:
+ break;
+ case 2:
+ AnEXTEN |= EXT_TIMES2;
+ break;
+ case 4:
+ AnEXTEN |= EXT_TIMES4;
+ break;
+ case 8:
+ AnEXTEN |= EXT_TIMES8;
+ break;
+ default:
+ goto badmode;
+ }
+ }
+
+ //Check for ]
+ if (*tok!=']')
+ return error("Expected closing bracket ]");
+ tok++; // Eat the bracket
+
+ //Check for od
+ if (*tok==')') // ([bd,An/PC,Xn]...
+ { //od is non existant, get out of jail free card
+ //AnEXVAL=0; // zero outer displacement
+ AMn=MEMPRE; // let's say it's ([bd,An,Xn],od) with od suppressed then
+ AnEXTEN|=EXT_IISPREN; // No outer displacement
+ tok++;
+ goto AnOK;
+ }
+ else if (*tok++!=',')
+ return error("comma expected after ]");
+ WARNING(Put symbol and constant checks here!)
+ if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
+ goto badmode;
+ if (optim_flags[OPT_BASE_DISP] && AnEXVAL==0)
+ {
+ // od=0 so optimise it out
+ AMn=MEMPRE; // let's say it's ([bd,An],Xn,od) with od=0 then
+ AnEXTEN|=EXT_IISPRE0; // No outer displacement
+ tok++;
+ goto AnOK;
+ }
+ // ([bd,An/PC,Xn],od)
+ if (*tok == DOTL)
+ {
+ // expr.L
+ AMn = MEMPRE;
+ tok++;
+
+ AnEXTEN|=EXT_IISPREL;
+
+ }
+ else
+ {
+ // expr.[W]
+ //tok++;
+
+ AnEXTEN|=EXT_IISPREW;
+ AMn = MEMPRE;
+
+ // Is .W forced here?
+ if (*tok == DOTW)
+ {
+ tok++;
+ }
+
+ // Defined, absolute values from $FFFF8000..$00007FFF get optimized
+ // to absolute short
+ else if (optim_flags[OPT_BASE_DISP] && (AnEXATTR & (TDB|DEFINED)) == DEFINED && (AnEXVAL + 0x8000) < 0x10000)
+ {
+ AnEXTEN|=EXT_IISPREW;
+ warn("outer displacement absolute value from $FFFF8000..$00007FFF optimised to absolute short");
+ }
+ }
+
+ // Check for final closing parenthesis
+ if (*tok==')')
+ {
+ tok++;
+ goto AnOK;
+ }
+ else
+ return error("Closing parenthesis missing on addressing mode");
+ }
+ else
+ goto badmode;
+
+ //goto unmode;
}
else
- { // (expr...
+ { // (expr...
if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
return ERROR;
goto AMn_IXN;
}
else if (*tok == ')')
- {
- AMn = ADISP;
- tok++;
- goto AnOK;
- }
+ {
+ AMn = ADISP;
+ tok++;
+ goto AnOK;
+ }
else
goto badmode;
}
}
else if (*tok == ')')
{
- AMn = PCDISP; // expr(PC)
+ AMn = PCDISP; // expr(PC)
tok++;
goto AnOK;
}
goto badmode;
}
}
- else if (*tok == '-' && tok[1] == '(' && ((tok[2] >= KW_A0) && (tok[2] <= KW_A7)) && tok[3] == ')')
+ else if (*tok=='-' && tok[1]=='(' && ((tok[2]>=KW_A0) && (tok[2]<=KW_A7)) && tok[3]==')')
{
AMn = APREDEC;
AnREG = tok[2] & 7;
{
AMn = AM_USP;
tok++;
+ AnREG=2; //Added this for the case of USP used in movec (see CREGlut in mach.c). Hopefully nothing gets broken!
+ goto AnOK;
+ }
+ else if ((*tok>=KW_IC40) && (*tok<=KW_BC40))
+ {
+ AMn=CACHES;
+ AnREG=*tok++-KW_IC40;
+
+ // After a cache keyword only a comma or EOL is allowed
+ if ((*tok!=',') && (*tok!=EOL))
+ return ERROR;
goto AnOK;
}
+ else if ((*tok>=KW_SFC) && (*tok<=KW_CRP))
+ {
+ AMn=CREG;
+ AnREG=(*tok++)-KW_SFC;
+ goto AnOK;
+ }
+ else if ((*tok>=KW_FP0) && (*tok<=KW_FP7))
+ {
+ AMn=FREG;
+ AnREG=(*tok++&7);
+ }
+ else if ((*tok>=KW_FPIAR) && (*tok<=KW_FPCR))
+ {
+ AMn=FPSCR;
+ AnREG=(1<<((*tok++)-KW_FPIAR+10));
+ }
// expr
// expr.w
// expr.l
CHK_FOR_DISPn:
if (*tok == DOTW)
{
- // expr.W
+ // expr.W
tok++;
AMn = ABSW;
#undef AMn_IX0
#undef AMn_IXN
#undef CHK_FOR_DISPn
+#undef AnBEXPR
+#undef AnBEXVAL
+#undef AnBEXATTR
+#undef AnBZISE
+#undef AnEXTEN
+#undef AMn_030
+#undef IS_SUPPRESSEDn
+#undef CHECKODn
int just_bss; // 1, ds.b in microprocessor mode
VALUE pcloc; // Value of "PC" at beginning of line
SYM * lab_sym; // Label on line (or NULL)
+int bfparam1; // bfxxx instruction parameters
+int bfparam2; // bfxxx instruction parameters
const char extra_stuff[] = "extra (unexpected) text found after addressing mode";
const char comma_error[] = "missing comma";
const char lab_ignored[] = "label ignored";
// Table to convert an addressing-mode number to a bitmask.
-LONG amsktab[0112] = {
+LONG amsktab[0124] = {
M_DREG, M_DREG, M_DREG, M_DREG,
M_DREG, M_DREG, M_DREG, M_DREG,
M_AM_USP, // 0106
M_AM_SR, // 0107
M_AM_CCR, // 0110
- M_AM_NONE // 0111
-}; // 0112 length
+ M_AM_NONE, // 0111
+ 0x30, // 0112
+ 0x30, // 0113
+ 0L, // 0114
+ 0L, // 0115
+ 0L, // 0116
+ 0L, // 0117
+ M_CREG, // 0120 (caches - TODO: is this correct or does it need its own bitfield?)
+ M_CREG, // 0121
+ M_FREG, // 0122
+ M_FPSCR // 0123
+}; // 0123 length
// Function prototypes
// First token MUST be a symbol (Shamus: not sure why :-/)
if (*tok != SYMBOL)
{
+ if (*tok>=KW_D0 && *tok<=KW_R31)
+ error("cannot use reserved keyword as label name or .equ");
+ else
error("syntax error; expected symbol");
goto loop;
}
siz = SIZL, tok++;
else if (*tok == DOTB)
siz = SIZB, tok++;
+ else if(*tok == DOTD)
+ siz = SIZD, tok++;
+ else if(*tok == DOTP)
+ siz = SIZP, tok++;
+ else if(*tok == DOTQ)
+ siz = SIZQ, tok++;
+ else if(*tok == DOTS)
+ siz = SIZS, tok++;
+ else if(*tok == DOTX)
+ siz = SIZX, tok++;
+
// Do special directives (500..999) (These must be handled in "real time")
if (state >= 500 && state < 1000)
#include "rmac.h"
#include "token.h"
+#include "amode.h"
// Exported variables
extern IFENT * ifent;
extern VALUE pcloc;
extern SYM * lab_sym;
extern LONG amsktab[];
+int bfparam1;
+int bfparam2;
+TOKEN bf0expr[EXPRSIZE]; // Expression
+VALUE bf0exval; // Expression's value
+WORD bf0exattr; // Expression's attribute
+SYM * bf0esym; // External symbol involved in expr
+
// Exported functions
void InitLineProcessor(void);
int d_if(void);
int d_else(void);
int d_endif(void);
+int check030bf(void);
#endif // __PROCLN_H__
int err_flag; // '-e' specified
int err_fd; // File to write error messages to
int rgpu, rdsp; // Assembling Jaguar GPU or DSP code
+int dsp56001; // Assembling DSP 56001 code
int list_fd; // File to write listing to
int regbank; // RISC register bank
int segpadsize; // Segment padding size
char * searchpath; // Search path for include files
char defname[] = "noname.o"; // Default output filename
int optim_flags[OPT_COUNT]; // Specific optimisations on/off matrix
+int activecpu=CPU_68000; // Active 68k CPU (68000 by default)
+int activefpu=FPU_NONE; // Active FPU (none by default)
//
// Manipulate file extension.
" o1: move.l #x,dn/an to moveq (on)\n"
" o2: Word branches to short (on)\n"
" o3: Outer displacement 0(an) to (an) (off)\n"
+ " o4: lea size(An),An to addq #size,An (off)\n"
+ " o5: Absolute long base displacement to word (off)\n"
" ~o[value] Turn a specific optimisation off\n"
" +oall Turn all optimisations on\n"
" ~oall Turn all optimisations off\n"
#define DOTW 'W' // .w or .W
#define DOTL 'L' // .l or .L
#define DOTI 'I' // .i or .I
+#define DOTD 'D' // .d or .D
+#define DOTS 'S' // .s or .S (FPU Single)
+#define DOTQ 'Q' // .q oe .Q (FPU Quad)
+#define DOTX 'X' // .x or .X (FPU Extended)
+#define DOTP 'P' // .p or .P (FPU Packed)
#define ENDEXPR 'E' // End of expression
// Object code formats
#define SIZW 0x0002 // .w
#define SIZL 0x0004 // .l
#define SIZN 0x0008 // no .(size) specifier
+#define SIZD 0x0010 // .d (quad word or FPU double precision real)
+#define SIZS 0x0020 // .s (FPU single precision real)
+#define SIZX 0x0040 // .x (FPU extended precision real)
+#define SIZP 0x0080 // .p (FPU pakced decimal real)
+#define SIZQ SIZD
// RISC register bank definitions (used in extended symbol attributes also)
#define BANK_N 0x0000 // No register bank specified
#define EQUATEDCC 0x0020
#define UNDEF_CC 0x0040
+/* Construct binary constants at compile time
+Code by Tom Torfs */
+
+/* Helper macros */
+#define HEX__(n) 0x##n##LU
+#define B8__(x) ((x&0x0000000FLU)?1:0) \
++((x&0x000000F0LU)?2:0) \
++((x&0x00000F00LU)?4:0) \
++((x&0x0000F000LU)?8:0) \
++((x&0x000F0000LU)?16:0) \
++((x&0x00F00000LU)?32:0) \
++((x&0x0F000000LU)?64:0) \
++((x&0xF0000000LU)?128:0)
+
+/* User macros */
+#define B8(d) ((unsigned char)B8__(HEX__(d)))
+#define B16(dmsb,dlsb) (((unsigned short)B8(dmsb)<<8) \
++ B8(dlsb))
+#define B32(dmsb,db2,db3,dlsb) (((unsigned long)B8(dmsb)<<24) \
++ ((unsigned long)B8(db2)<<16) \
++ ((unsigned long)B8(db3)<<8) \
++ B8(dlsb))
+
// Optimisation defines
enum
{
OPT_MOVEL_MOVEQ = 1,
OPT_BSR_BCC_S = 2,
OPT_INDIRECT_DISP = 3,
+ OPT_LEA_ADDQ = 4,
+ OPT_BASE_DISP = 5,
OPT_COUNT // Dummy, used to count number of optimisation switches
};
extern int verb_flag;
extern int debug;
extern int rgpu, rdsp;
+extern int dsp56001;
extern int err_flag;
extern int err_fd;
extern int regbank;
CHUNK * sfix; // Last fixup chunk
};
+// 680x0 defines
+#define CPU_68000 1
+#define CPU_68020 2
+#define CPU_68030 4
+#define CPU_68040 8
+#define CPU_68060 16
+#define FPU_NONE 0
+#define FPU_68881 1
+#define FPU_68882 2
+#define FPU_68040 4
+
+// Helper macros to test for active CPU
+#define CHECK00 if (activecpu == CPU_68000) return error(unsupport)
+#define CHECK20 if (activecpu == CPU_68020) return error(unsupport)
+#define CHECK30 if (activecpu == CPU_68030) return error(unsupport)
+#define CHECK40 if (activecpu == CPU_68040) return error(unsupport)
+#define CHECK60 if (activecpu == CPU_68060) return error(unsupport)
+#define CHECKNO00 if (activecpu != CPU_68000) return error(unsupport)
+#define CHECKNO20 if (activecpu != CPU_68020) return error(unsupport)
+#define CHECKNO30 if (activecpu != CPU_68030) return error(unsupport)
+#define CHECKNO40 if (activecpu != CPU_68040) return error(unsupport)
+#define CHECKNO60 if (activecpu != CPU_68060) return error(unsupport)
+
+
// Globals, external etc
extern uint32_t sloc;
extern uint16_t scattr;
MULTX, STSYM+CTSYM+HDIGIT, // @ A
(char)((BYTE)DOT)+STSYM+CTSYM+HDIGIT, STSYM+CTSYM+HDIGIT, // B C
- STSYM+CTSYM+HDIGIT, STSYM+CTSYM+HDIGIT, // D E
+ (char)((BYTE)DOT)+STSYM+CTSYM+HDIGIT, STSYM+CTSYM+HDIGIT, // D E
STSYM+CTSYM+HDIGIT, STSYM+CTSYM, // F G
- STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, // H I J K
+ STSYM+CTSYM, (char)((BYTE)DOT)+STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, // H I J K
(char)((BYTE)DOT)+STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, // L M N O
- STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, (char)((BYTE)DOT)+STSYM+CTSYM, // P Q R S
+ (char)((BYTE)DOT)+STSYM+CTSYM, (char)((BYTE)DOT)+STSYM+CTSYM, STSYM+CTSYM, (char)((BYTE)DOT)+STSYM+CTSYM, // P Q R S
STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, (char)((BYTE)DOT)+STSYM+CTSYM, // T U V W
STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, SELF, // X Y Z [
SELF, SELF, MULTX, STSYM+CTSYM, // \ ] ^ _
ILLEG, STSYM+CTSYM+HDIGIT, // ` a
(char)((BYTE)DOT)+STSYM+CTSYM+HDIGIT, STSYM+CTSYM+HDIGIT, // b c
- STSYM+CTSYM+HDIGIT, STSYM+CTSYM+HDIGIT, // d e
+ (char)((BYTE)DOT)+STSYM+CTSYM+HDIGIT, STSYM+CTSYM+HDIGIT, // d e
STSYM+CTSYM+HDIGIT, STSYM+CTSYM, // f g
- STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, // h i j k
+ STSYM+CTSYM, (char)((BYTE)DOT)+STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, // h i j k
(char)((BYTE)DOT)+STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, // l m n o
- STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, (char)((BYTE)DOT)+STSYM+CTSYM, // p q r s
- STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, (char)((BYTE)DOT)+STSYM+CTSYM, // t u v w
- STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, SELF, // x y z {
+ (char)((BYTE)DOT)+STSYM+CTSYM, (char)((BYTE)DOT)+STSYM+CTSYM, STSYM+CTSYM, (char)((BYTE)DOT)+STSYM+CTSYM, // p q r s
+ STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, (char)((BYTE)DOT)+STSYM+CTSYM, // t u v w
+ (char)((BYTE)DOT)+STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, SELF, // x y z {
SELF, SELF, SELF, ILLEG // | } ~ DEL
};
// Names of registers
static char * regname[] = {
- "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
- "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7",
- "pc", "ssp", "usp", "sr", "ccr"
+// "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
+// "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7",
+// "pc", "ssp", "usp", "sr", "ccr"
+ "d0","d1","d2","d3","d4","d5","d6","d7", // 128,135
+ "a0","a1","a2","a3","a4","a5","a6","sp", // 136,143
+ "ssp","pc","sr","ccr","regequ","set","reg","r0", // 144,151
+ "r1","r2","r3","r4","r5","r6","r7","r8", // 152,159
+ "r9","r10","r11","r12","r13","r14","r15","r16", // 160,167
+ "r17","r18","r19","r20","r21","r22","r23","r24", // 168,175
+ "r25","r26","r27","r28","r29","r30","r31","ccdef", // 176,183
+ "usp","ic40","dc40","bc40","sfc","dfc","","vbr", // 184,191
+ "cacr","caar","msp","isp","tc","itt0","itt1","dtt0", // 192,199
+ "dtt1","mmusr","urp","srp","iacr0","iacr1","dacr0","dacr1", // 200,207
+ "tt0","tt1","crp","","","","","", // 208,215
+ "","","","","fpiar","fpsr","fpcr","", // 216,223
+ "fp0","fp1","fp2","fp3","fp4","fp5","fp6","fp7", // 224,231
+ "","","","","","","","", // 232,239
+ "","","","","","","","", // 240,247
+ "","","","","","","","", // 248,255
+ "","","","","x0","x1","y0","y1", // 256,263
+ "","b0","","b2","","b1","a","b", // 264,271
+ "mr","omr","la","lc","ssh","ssl","ss","", // 272,279
+ "n0","n1","n2","n3","n4","n5","n6","n7", // 280,287
+ "m0","m1","m2","m3","m4","m5","m6","m7", // 288,295
+ "","","","","","","l","p", // 296,303
+ "mr","omr","la","lc","ssh","ssl","ss","", // 304,311
+ "a10","b10","x","y","","","ab","ba" // 312,319
};
static char * riscregname[] = {
// These characters are legal immediately after a period
dotxtab['b'] = DOTB; // .b .B .s .S
dotxtab['B'] = DOTB;
- dotxtab['s'] = DOTB;
- dotxtab['S'] = DOTB;
- dotxtab['w'] = DOTW; // .w .W
+ //dotxtab['s'] = DOTB;
+ //dotxtab['S'] = DOTB;
+ dotxtab['w'] = DOTW; // .w .W
dotxtab['W'] = DOTW;
- dotxtab['l'] = DOTL; // .l .L
+ dotxtab['l'] = DOTL; // .l .L
dotxtab['L'] = DOTL;
- dotxtab['i'] = DOTI; // .i .I (???)
+ dotxtab['i'] = DOTI; // .i .I (???)
dotxtab['I'] = DOTI;
+ dotxtab['D'] = DOTD; // .d .D (quad word)
+ dotxtab['d'] = DOTD;
+ dotxtab['S'] = DOTS; // .s .S
+ dotxtab['s'] = DOTS;
+ dotxtab['Q'] = DOTQ; // .q .Q
+ dotxtab['q'] = DOTQ;
+ dotxtab['X'] = DOTX; // .x .x
+ dotxtab['x'] = DOTX;
+ dotxtab['P'] = DOTP; // .p .P
+ dotxtab['p'] = DOTP;
}
while (hextab[*ln] >= 0)
v = (v << 4) + (int)hextab[*ln++];
- // ggn: Okay, some comments here are in order I think....
- // The original madmac sources didn't parse the size at
- // this point (i.e. .b/.w/.l). It was probably done at
- // another point, although it's unclear to me exactly
- // where. So why change this? My understanding (at least
- // from what SCPCD said on IRC) is that .w addressing
- // formats produce wrong code on jaguar (or doesn't execute
- // properly? something like that). So the code was changed
- // to mask off the upper bits depending on length (note: I
- // don't think .b is valid at all! I only know of .w/.l, so
- // this should probably be wiped). Then the code that
- // parses the constant and checks to see if it's between
- // $ffff0000 and $8000 never got triggered, so yay job
- // done! ...now say we want to assemble a st .prg. One of
- // the most widely spread optimisations is move.X expr.w,Y
- // (or vice versa, or both, anyway...) to access hardware
- // registers (which are mapped to $fxxxxx). This botchy
- // thing would create "hilarious" code while trying to
- // access hardware registers. So I made a condition to see
- // if st mode or jaguar is active and apply the both or
- // not. One last note: this is hardcoded to get optimised
- // for now on ST mode, i.e. it can't generate code like
- // move.w $00001234,d0 - it'll always get optimised to
- // move.w $1234.w,d0. It's probably ok, but maybe a warning
- // should be emitted? Or maybe finding a way to make it not
- // auto-optimise? I think it's ok for now...
if (*ln == '.')
{
if (obj_format == BSD)
#define DOTW 'W' // .w or .W
#define DOTL 'L' // .l or .L
#define DOTI 'I' // .l or .L
+#define DOTX 'X' // .x or .X
+#define DOTD 'D' // .d or .D
+#define DOTP 'P' // .p or .P
+#define DOTQ 'Q' // .q or .Q (essentially an alias for P)
#define ENDEXPR 'E' // End of expression
// ^^ operators
extern char lntag;
extern char tolowertab[];
extern INOBJ * cur_inobj;
+extern unsigned orgactive;
+extern unsigned orgaddr;
+extern LONG sloc;
extern int mjump_align;
extern char * string[];