From: ggn Date: Fri, 5 May 2017 14:51:11 +0000 (+0300) Subject: Initial commit for 68020/30/40/60/68881/68882/68851 support. X-Git-Tag: v2.1.0~123 X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=rmac;a=commitdiff_plain;h=5cd8a4814b805f1ef8ce689423eb5eeba12573c5;hp=51cff2ac6cb3d097f62b68c51d74fafbce8923f6 Initial commit for 68020/30/40/60/68881/68882/68851 support. --- diff --git a/68ktab b/68ktab index 1427a03..e250bf7 100644 --- a/68ktab +++ b/68ktab @@ -27,25 +27,39 @@ asr NBWL M_DREG M_DREG %1110rrr0ss100rrr m_shr + - 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 + @@ -57,7 +71,18 @@ bclr NL M_DREG M_DREG %0000rrr110eeeeee 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 + @@ -65,14 +90,27 @@ 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 @@ -83,6 +121,87 @@ cmpa NWL C_ALL M_AREG %1011rrrs11eeeeee m_adda + 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 @@ -105,9 +224,17 @@ dbt NW M_DREG C_LABEL %0101000011001rrr m_dbra 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 + @@ -118,16 +245,349 @@ exg NL M_DREG|M_AREG M_DREG|M_AREG %1100rrr1ooooorrr m_exg 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 + @@ -145,10 +605,22 @@ move NBWL C_ALL C_ALTDATA %00ssddddddssssss m_move + - 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 + @@ -156,8 +628,11 @@ 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 @@ -170,6 +645,92 @@ ori NBWL M_IMMED C_ALTDATA %00000000sseeeS11 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 @@ -194,7 +755,9 @@ roxr NBWL M_DREG M_DREG %1110rrr0ss110rrr m_shr + - 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 @@ -237,6 +800,43 @@ subx NBWL M_DREG M_DREG %1001xxx1ss000yyS m_abcd + 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 diff --git a/Vs2015/rmac/rmac.vcxproj b/Vs2015/rmac/rmac.vcxproj index d544059..9e481bf 100644 --- a/Vs2015/rmac/rmac.vcxproj +++ b/Vs2015/rmac/rmac.vcxproj @@ -151,6 +151,10 @@ Console true + + cd $(SolutionDir)..\ +call maketabs.bat + diff --git a/amode.c b/amode.c index f0734ea..be5162b 100644 --- a/amode.c +++ b/amode.c @@ -1,7 +1,7 @@ // // 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 // @@ -11,110 +11,188 @@ #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"); } @@ -123,51 +201,230 @@ int amode(int acount) // 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 {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, {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; +} diff --git a/amode.h b/amode.h index 380b460..a62a5fa 100644 --- a/amode.h +++ b/amode.h @@ -34,6 +34,10 @@ #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 @@ -50,7 +54,7 @@ #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) @@ -58,6 +62,10 @@ #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 @@ -65,6 +73,10 @@ #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) @@ -72,18 +84,50 @@ #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; @@ -93,6 +137,11 @@ extern TOKEN a0oexpr[], a1oexpr[]; 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 @@ -110,6 +159,7 @@ MNTAB { // Exported functions int amode(int); int reglist(WORD *); - +int fpu_reglist_left(WORD *); +int fpu_reglist_right(WORD *); #endif // __AMODE_H__ diff --git a/direct.c b/direct.c index a736855..7076358 100644 --- a/direct.c +++ b/direct.c @@ -66,6 +66,7 @@ int d_fail(void); int d_cstruct(void); int d_prgflags(void); int d_opt(void); +int d_dsp(void); // Directive handler table int (*dirtab[])() = { @@ -127,6 +128,14 @@ 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 }; @@ -1041,15 +1050,15 @@ int d_dc(WORD siz) } 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); } @@ -1376,9 +1385,88 @@ int d_68000(void) 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 diff --git a/direct.h b/direct.h index 27219e5..8eb1690 100644 --- a/direct.h +++ b/direct.h @@ -24,10 +24,63 @@ int abs_expr(VALUE *); 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__ diff --git a/eagen.c b/eagen.c index ca87fcc..c52e877 100644 --- a/eagen.c +++ b/eagen.c @@ -13,6 +13,7 @@ #include "error.h" #include "mach.h" #include "riscasm.h" +#include "sect.h" #define eaNgen ea0gen #define amN am0 @@ -22,6 +23,9 @@ #define aNixreg a0ixreg #define aNixsiz a0ixsiz #define AnESYM a0esym +#define aNexten a0extension +#define aNbdexval a0bexval +#define aNbdexattr a0bexattr #include "eagen0.c" #define eaNgen ea1gen @@ -32,4 +36,7 @@ #define aNixreg a1ixreg #define aNixsiz a1ixsiz #define AnESYM a1esym +#define aNexten a1extension +#define aNbdexval a1bexval +#define aNbdexattr a1bexattr #include "eagen0.c" diff --git a/eagen0.c b/eagen0.c index a9b6f7e..5597eb0 100644 --- a/eagen0.c +++ b/eagen0.c @@ -9,9 +9,12 @@ 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) { @@ -212,6 +215,10 @@ int eaNgen(WORD siz) } break; + case SIZP: + // 68881/68882/68040 only + return error("Sorry, .p constant format is not implemented yet!"); + break; case ABSW: if (w) // Defined { @@ -251,7 +258,100 @@ int eaNgen(WORD siz) 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); @@ -268,5 +368,8 @@ int eaNgen(WORD siz) #undef aNexpr #undef aNixreg #undef aNixsiz +#undef aNexten +#undef aNbdexval +#undef aNbdexattr #undef AnESYM diff --git a/error.h b/error.h index aa431a5..30021d9 100644 --- a/error.h +++ b/error.h @@ -11,7 +11,7 @@ #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; diff --git a/expr.c b/expr.c index 4c4168f..01868e8 100644 --- a/expr.c +++ b/expr.c @@ -287,6 +287,20 @@ int expr2(void) *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"); diff --git a/kwgen.c b/kwgen.c index 55bd32a..16ba5f6 100644 --- a/kwgen.c +++ b/kwgen.c @@ -40,8 +40,8 @@ * 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 */ diff --git a/kwtab b/kwtab index 70c33d2..66ac579 100644 --- a/kwtab +++ b/kwtab @@ -23,6 +23,58 @@ pc 145 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 @@ -30,6 +82,7 @@ equr 148 .regequ 148 regequ 148 set 149 + reg 150 r0 151 r1 152 diff --git a/mach.c b/mach.c index 71fd3cb..19dc67d 100644 --- a/mach.c +++ b/mach.c @@ -22,32 +22,6 @@ // 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"; @@ -56,6 +30,11 @@ char rel_error[] = "illegal relative address"; 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[] = { @@ -97,6 +76,15 @@ WORD lwsiz_8[] = { 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, @@ -109,6 +97,35 @@ WORD am_6[] = { 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) @@ -127,7 +144,7 @@ int m_badmode(WORD unused1, WORD unused2) int m_self(WORD inst, WORD usused) { D_word(inst); - return 0; + return OK; } @@ -190,7 +207,92 @@ int m_ea(WORD inst, WORD siz) 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; } @@ -210,7 +312,7 @@ int m_abcd(WORD inst, WORD siz) inst |= a0reg | reg_9[a1reg]; D_word(inst); - return 0; + return OK; } @@ -223,7 +325,7 @@ int m_adda(WORD inst, WORD siz) D_word(inst); ea0gen(siz); // Generate EA - return 0; + return OK; } @@ -245,7 +347,7 @@ int m_reg(WORD inst, WORD siz) inst |= a0reg; // Install first register D_word(inst); - return 0; + return OK; } @@ -257,7 +359,7 @@ int m_imm(WORD inst, WORD siz) D_word(inst); ea0gen(siz); - return 0; + return OK; } @@ -270,7 +372,7 @@ int m_imm8(WORD inst, WORD siz) D_word(inst); ea0gen(SIZB); - return 0; + return OK; } @@ -282,7 +384,7 @@ int m_shr(WORD inst, WORD siz) inst |= reg_9[a0reg] | a1reg | siz_6[siz]; D_word(inst); - return 0; + return OK; } @@ -307,7 +409,7 @@ int m_shi(WORD inst, WORD siz) D_word(inst); } - return 0; + return OK; } @@ -342,7 +444,7 @@ int m_bitop(WORD inst, WORD siz) // ea to bit-munch ea1gen(SIZB); - return 0; + return OK; } @@ -372,7 +474,7 @@ int m_dbra(WORD inst, WORD siz) D_word(0); } - return 0; + return OK; } @@ -404,7 +506,7 @@ int m_exg(WORD inst, WORD siz) inst |= m | reg_9[a0reg] | a1reg; D_word(inst); - return 0; + return OK; } @@ -413,14 +515,42 @@ int m_exg(WORD inst, WORD siz) // 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 @@ -444,6 +574,8 @@ int m_move(WORD inst, WORD size) } else { + if (am0= 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 +// MOVE +// +int m_move30(WORD inst, WORD size) +{ + // Cast the passed in value to an int + int siz = (int)size; + + /*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; } @@ -473,7 +655,7 @@ int m_usp(WORD inst, WORD siz) D_word(inst); - return 0; + return OK; } @@ -496,7 +678,7 @@ int m_moveq(WORD inst, WORD siz) inst |= reg_9[a1reg] | (a0exval & 0xFF); D_word(inst); - return 0; + return OK; } // @@ -561,7 +743,7 @@ int m_br(WORD inst, WORD siz) D_word(inst); if (sbra_flag) warn("Bcc.w/BSR.w converted to .s"); - return 0; + return OK; } else { @@ -571,11 +753,11 @@ int m_br(WORD inst, WORD siz) 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); @@ -592,17 +774,17 @@ int m_br(WORD inst, WORD siz) 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 { @@ -612,7 +794,7 @@ int m_br(WORD inst, WORD siz) D_word(0); } - return 0; + return OK; } @@ -639,7 +821,7 @@ int m_addq(WORD inst, WORD siz) ea1gen(siz); - return 0; + return OK; } @@ -664,7 +846,7 @@ int m_trap(WORD inst, WORD siz) else return error(undef_error); - return 0; + return OK; } @@ -690,7 +872,7 @@ int m_movem(WORD inst, WORD siz) tok++; if (abs_expr(&eval) != OK) - return 0; + return OK; if (eval >= 0x10000L) return error(range_error); @@ -703,14 +885,14 @@ int m_movem(WORD inst, WORD siz) { // , 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; @@ -731,7 +913,7 @@ immed1: { // ea, if (amode(0) < 0) - return 0; + return OK; inst |= 0x0400 | am0 | a0reg; @@ -747,7 +929,7 @@ immed1: tok++; if (abs_expr(&eval) != OK) - return 0; + return OK; if (eval >= 0x10000) return error(range_error); @@ -755,7 +937,7 @@ immed1: rmask = (WORD)eval; } else if (reglist(&rmask) < 0) - return 0; + return OK; if (!(amsktab[am0] & (C_CTRL | M_APOSTINC))) return error("invalid addressing mode"); @@ -765,7 +947,7 @@ immed1: D_word(rmask); ea0gen(siz); - return 0; + return OK; } @@ -777,6 +959,2301 @@ int m_clra(WORD inst, WORD siz) 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 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&&am1ea + + //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 (am0fpx + + //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=KW_FP0 && *tok<=KW_FP7) + { + //fmovem.x ,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, + 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 ,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, + 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); } diff --git a/mach.h b/mach.h index b95636e..8b10038 100644 --- a/mach.h +++ b/mach.h @@ -9,6 +9,7 @@ #ifndef __MACH_H__ #define __MACH_H__ +#include "rmac.h" #include "amode.h" // Exported variables @@ -18,7 +19,264 @@ extern char rel_error[]; 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__ diff --git a/makefile b/makefile index 747f4cc..c7683af 100644 --- a/makefile +++ b/makefile @@ -34,7 +34,7 @@ OBJS = 6502.o amode.o debug.o direct.o eagen.o error.o expr.o listing.o mach.o m # 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 @@ -50,10 +50,11 @@ mntab.h : mntab 68kmn kwgen 68ktab.h 68kmn : 68ktab 68ktab 68kgen ./68kgen 68kmn <68ktab >68ktab.h + kwtab.h : kwtab kwgen ./kwgen kw kwtab.h -6502.h : 6502.tbl kwgen +6502kw.h : 6502.tbl kwgen ./kwgen mp <6502.tbl >6502kw.h risckw.h : kwtab kwgen diff --git a/mark.c b/mark.c index 70f90fd..f5eb2af 100644 --- a/mark.c +++ b/mark.c @@ -95,8 +95,8 @@ if (symbol) // 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'", diff --git a/mntab b/mntab index 57cf325..b65271a 100644 --- a/mntab +++ b/mntab @@ -99,12 +99,24 @@ nojpad 55 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 @@ -119,135 +131,3 @@ rept 506 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 diff --git a/parmode.h b/parmode.h index 5518343..8b0456f 100644 --- a/parmode.h +++ b/parmode.h @@ -74,6 +74,63 @@ 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++; @@ -144,10 +201,488 @@ } 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: | .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: | .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: | .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; @@ -174,11 +709,11 @@ goto AMn_IXN; } else if (*tok == ')') - { - AMn = ADISP; - tok++; - goto AnOK; - } + { + AMn = ADISP; + tok++; + goto AnOK; + } else goto badmode; } @@ -191,7 +726,7 @@ } else if (*tok == ')') { - AMn = PCDISP; // expr(PC) + AMn = PCDISP; // expr(PC) tok++; goto AnOK; } @@ -202,7 +737,7 @@ 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; @@ -224,8 +759,35 @@ { 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 @@ -241,7 +803,7 @@ CHK_FOR_DISPn: if (*tok == DOTW) { - // expr.W + // expr.W tok++; AMn = ABSW; @@ -328,3 +890,11 @@ CHK_FOR_DISPn: #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 diff --git a/procln.c b/procln.c index c4612cb..65d7580 100644 --- a/procln.c +++ b/procln.c @@ -41,6 +41,8 @@ static int disabled; // Assembly conditionally disabled 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"; @@ -49,7 +51,7 @@ const char locgl_error[] = "cannot GLOBL local symbol"; 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, @@ -88,8 +90,18 @@ LONG amsktab[0112] = { 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 @@ -177,6 +189,9 @@ loop1: // Internal line processing loop // 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; } @@ -261,6 +276,17 @@ as68label: 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) diff --git a/procln.h b/procln.h index ccb958f..c85312a 100644 --- a/procln.h +++ b/procln.h @@ -11,6 +11,7 @@ #include "rmac.h" #include "token.h" +#include "amode.h" // Exported variables extern IFENT * ifent; @@ -22,6 +23,13 @@ extern int just_bss; 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); @@ -29,6 +37,7 @@ void Assemble(void); int d_if(void); int d_else(void); int d_endif(void); +int check030bf(void); #endif // __PROCLN_H__ diff --git a/rmac.c b/rmac.c index 1cddbf6..a24b614 100644 --- a/rmac.c +++ b/rmac.c @@ -39,6 +39,7 @@ int debug; // [1..9] Enable debugging levels 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 @@ -49,6 +50,8 @@ char * cmdlnexec; // Executable name, pointer to ARGV[0] 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. @@ -144,6 +147,8 @@ void DisplayHelp(void) " 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" diff --git a/rmac.h b/rmac.h index 00eba54..2b71ac7 100644 --- a/rmac.h +++ b/rmac.h @@ -188,6 +188,11 @@ #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 @@ -236,6 +241,11 @@ PTR #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 @@ -246,6 +256,29 @@ PTR #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 { @@ -253,6 +286,8 @@ 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 }; @@ -260,6 +295,7 @@ enum 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; diff --git a/sect.h b/sect.h index ccb81b1..129b1cc 100644 --- a/sect.h +++ b/sect.h @@ -113,6 +113,30 @@ SECT { 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; diff --git a/token.c b/token.c index 01c0c4c..75b4cc1 100644 --- a/token.c +++ b/token.c @@ -81,34 +81,58 @@ char chrtab[] = { 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[] = { @@ -159,14 +183,24 @@ void InitTokenizer(void) // 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; } @@ -1251,32 +1285,6 @@ dostring: 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) diff --git a/token.h b/token.h index 4ea6702..9adabef 100644 --- a/token.h +++ b/token.h @@ -53,6 +53,10 @@ #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 @@ -146,6 +150,9 @@ extern char lnbuf[]; 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[];