diff --git a/librz/arch/isa/milstd1750/milstd1750_disas.c b/librz/arch/isa/milstd1750/milstd1750_disas.c index 799fd478526..bbb093d2842 100644 --- a/librz/arch/isa/milstd1750/milstd1750_disas.c +++ b/librz/arch/isa/milstd1750/milstd1750_disas.c @@ -37,43 +37,43 @@ typedef struct { } MilStd1750XioCommand; static const MilStd1750XioCommand milstd1750_xio_commands[] = { - { 0x2000, "SMK" }, - { 0x2001, "CLIR" }, - { 0x2002, "ENBL" }, - { 0x2003, "DSBL" }, - { 0x2004, "RPI" }, - { 0x2005, "SPI" }, - { 0x200E, "WSW" }, - { 0xA000, "RMK" }, - { 0xA004, "RPIR" }, - { 0xA00E, "RSW" }, - { 0xA00F, "RCFR" }, - { 0x2008, "OD" }, - { 0x200A, "RNS" }, - { 0x4000, "CO" }, - { 0x4001, "CLC" }, - { 0x4003, "MPEN" }, - { 0x4004, "ESUR" }, - { 0x4005, "DSUR" }, - { 0x4006, "DMAE" }, - { 0x4007, "DMAD" }, - { 0x4008, "TAS" }, - { 0x4009, "TAH" }, - { 0x400A, "OTA" }, - { 0x400B, "GO" }, - { 0x400C, "TBS" }, - { 0x400D, "TBH" }, - { 0x400E, "OTB" }, - { 0xA001, "RIC1" }, - { 0xA002, "RIC2" }, - { 0xA008, "RDOR" }, - { 0xA009, "RDI" }, - { 0xA00B, "TPIO" }, - { 0xA00D, "RMFS" }, - { 0xC000, "CI" }, - { 0xC001, "RCS" }, - { 0xC00A, "ITA" }, - { 0xC00E, "ITB" }, + { MIL_XIO_SMK, "SMK" }, + { MIL_XIO_CLIR, "CLIR" }, + { MIL_XIO_ENBL, "ENBL" }, + { MIL_XIO_DSBL, "DSBL" }, + { MIL_XIO_RPI, "RPI" }, + { MIL_XIO_SPI, "SPI" }, + { MIL_XIO_WSW, "WSW" }, + { MIL_XIO_RMK, "RMK" }, + { MIL_XIO_RPIR, "RPIR" }, + { MIL_XIO_RSW, "RSW" }, + { MIL_XIO_RCFR, "RCFR" }, + { MIL_XIO_OD, "OD" }, + { MIL_XIO_RNS, "RNS" }, + { MIL_XIO_CO, "CO" }, + { MIL_XIO_CLC, "CLC" }, + { MIL_XIO_MPEN, "MPEN" }, + { MIL_XIO_ESUR, "ESUR" }, + { MIL_XIO_DSUR, "DSUR" }, + { MIL_XIO_DMAE, "DMAE" }, + { MIL_XIO_DMAD, "DMAD" }, + { MIL_XIO_TAS, "TAS" }, + { MIL_XIO_TAH, "TAH" }, + { MIL_XIO_OTA, "OTA" }, + { MIL_XIO_GO, "GO" }, + { MIL_XIO_TBS, "TBS" }, + { MIL_XIO_TBH, "TBH" }, + { MIL_XIO_OTB, "OTB" }, + { MIL_XIO_RIC1, "RIC1" }, + { MIL_XIO_RIC2, "RIC2" }, + { MIL_XIO_RDOR, "RDOR" }, + { MIL_XIO_RDI, "RDI" }, + { MIL_XIO_TPIO, "TPIO" }, + { MIL_XIO_RMFS, "RMFS" }, + { MIL_XIO_CI, "CI" }, + { MIL_XIO_RCS, "RCS" }, + { MIL_XIO_ITA, "ITA" }, + { MIL_XIO_ITB, "ITB" }, }; static char *format_xio_command(ut16 cmd) { @@ -158,215 +158,215 @@ static char *format_xio_command(ut16 cmd) { */ // clang-format off static const MilStd1750LongInstruction milstd1750_inst_tab[] = { - { 0x4040, "ABX", MIL_FMT_BX, }, - { 0x40E0, "ANDX", MIL_FMT_BX, }, - { 0xA000, "A", MIL_FMT_MEM, }, - { 0xA400, "ABS", MIL_FMT_R, }, - { 0x4A01, "AIM", MIL_FMT_IM_OCX, }, - { 0xA200, "AISP", MIL_FMT_IS, }, - { 0xE200, "AND", MIL_FMT_MEM, }, - { 0x3400, "ANDB", MIL_FMT_B, }, - { 0x4A07, "ANDM", MIL_FMT_IM_OCX, }, - { 0xE300, "ANDR", MIL_FMT_R, }, - { 0xA100, "AR", MIL_FMT_R, }, - { 0x1000, "AB", MIL_FMT_B, }, - { 0x7700, "BEX", MIL_FMT_S, }, - { 0x7500, "BEZ", MIL_FMT_ICR, }, - { 0x7B00, "BGE", MIL_FMT_ICR, }, - { 0x7900, "BGT", MIL_FMT_ICR, }, - { 0x4F00, "BIF", MIL_FMT_S, }, - { 0x7800, "BLE", MIL_FMT_ICR, }, - { 0x7600, "BLT", MIL_FMT_ICR, }, - { 0x7A00, "BNZ", MIL_FMT_ICR, }, - { 0xFFFF, "BPT", MIL_FMT_NONE, }, - { 0x7400, "BR", MIL_FMT_ICR, }, - { 0xF000, "C", MIL_FMT_MEM, }, - { 0x3800, "CB", MIL_FMT_B, }, - { 0xF400, "CBL", MIL_FMT_MEM, }, - { 0x40C0, "CBX", MIL_FMT_BX, }, - { 0xF100, "CR", MIL_FMT_R, }, - { 0xF200, "CISP", MIL_FMT_IS, }, - { 0xF300, "CISN", MIL_FMT_IS, }, - { 0x4A0A, "CIM", MIL_FMT_IM_OCX, }, - { 0xD700, "DDR", MIL_FMT_R, }, - { 0xD600, "DD", MIL_FMT_MEM, }, - { 0xD400, "D", MIL_FMT_MEM, }, - { 0xA600, "DA", MIL_FMT_MEM, }, - { 0xA500, "DABS", MIL_FMT_R, }, - { 0xA700, "DAR", MIL_FMT_R, }, - { 0x1C00, "DB", MIL_FMT_B, }, - { 0xF600, "DC", MIL_FMT_MEM, }, - { 0xF700, "DCR", MIL_FMT_R, }, - { 0xB300, "DECM", MIL_FMT_IM_1_16, }, - { 0x4A05, "DIM", MIL_FMT_IM_OCX, }, - { 0xD300, "DISN", MIL_FMT_IS, }, - { 0xD200, "DISP", MIL_FMT_IS, }, - { 0x8600, "DL", MIL_FMT_MEM, }, - { 0x0400, "DLB", MIL_FMT_B, }, - { 0x4010, "DLBX", MIL_FMT_BX, }, - { 0xDF00, "DLE", MIL_FMT_MEM, }, - { 0x8800, "DLI", MIL_FMT_MEM, }, - { 0x8700, "DLR", MIL_FMT_R, }, - { 0xC600, "DM", MIL_FMT_MEM, }, - { 0xC700, "DMR", MIL_FMT_R, }, - { 0xB500, "DNEG", MIL_FMT_R, }, - { 0xD500, "DR", MIL_FMT_R, }, - { 0xB600, "DS", MIL_FMT_MEM, }, - { 0x6E00, "DSAR", MIL_FMT_R, }, - { 0x6F00, "DSCR", MIL_FMT_R, }, - { 0x6500, "DSLL", MIL_FMT_R_IMM, }, - { 0x6800, "DSLC", MIL_FMT_R_IMM, }, - { 0x6D00, "DSLR", MIL_FMT_R, }, - { 0x6700, "DSRA", MIL_FMT_R_IMM, }, - { 0x6600, "DSRL", MIL_FMT_R_IMM, }, - { 0xB700, "DSR", MIL_FMT_R, }, - { 0x9600, "DST", MIL_FMT_MEM, }, - { 0x0C00, "DSTB", MIL_FMT_B, }, - { 0x9800, "DSTI", MIL_FMT_MEM, }, - { 0xDD00, "DSTE", MIL_FMT_MEM, }, - { 0x4030, "DSTX", MIL_FMT_BX, }, - { 0xD000, "DV", MIL_FMT_MEM, }, - { 0x4A06, "DVIM", MIL_FMT_IM_OCX, }, - { 0xD100, "DVR", MIL_FMT_R, }, - { 0x4070, "DBX", MIL_FMT_BX, }, - { 0xEB00, "EFLT", MIL_FMT_R, }, - { 0xEA00, "EFIX", MIL_FMT_R, }, - { 0xFA00, "EFC", MIL_FMT_MEM, }, - { 0xFB00, "EFCR", MIL_FMT_R, }, - { 0xAA00, "EFA", MIL_FMT_MEM, }, - { 0xAB00, "EFAR", MIL_FMT_R, }, - { 0xDA00, "EFD", MIL_FMT_MEM, }, - { 0xDB00, "EFDR", MIL_FMT_R, }, - { 0x8A00, "EFL", MIL_FMT_MEM, }, - { 0xCA00, "EFM", MIL_FMT_MEM, }, - { 0xCB00, "EFMR", MIL_FMT_R, }, - { 0xBA00, "EFS", MIL_FMT_MEM, }, - { 0xBB00, "EFSR", MIL_FMT_R, }, - { 0x9A00, "EFST", MIL_FMT_MEM, }, - { 0xAC00, "FABS", MIL_FMT_R, }, - { 0xA800, "FA", MIL_FMT_MEM, }, - { 0x2000, "FAB", MIL_FMT_B, }, - { 0x4080, "FABX", MIL_FMT_BX, }, - { 0xA900, "FAR", MIL_FMT_R, }, - { 0xF800, "FC", MIL_FMT_MEM, }, - { 0x3C00, "FCB", MIL_FMT_B, }, - { 0x40D0, "FCBX", MIL_FMT_BX, }, - { 0xF900, "FCR", MIL_FMT_R, }, - { 0xD800, "FD", MIL_FMT_MEM, }, - { 0x2C00, "FDB", MIL_FMT_B, }, - { 0x40B0, "FDBX", MIL_FMT_BX, }, - { 0xD900, "FDR", MIL_FMT_R, }, - { 0xE800, "FIX", MIL_FMT_R, }, - { 0xE900, "FLT", MIL_FMT_R, }, - { 0xC800, "FM", MIL_FMT_MEM, }, - { 0x2800, "FMB", MIL_FMT_B, }, - { 0x40A0, "FMBX", MIL_FMT_BX, }, - { 0xC900, "FMR", MIL_FMT_R, }, - { 0xBC00, "FNEG", MIL_FMT_R, }, - { 0xB800, "FS", MIL_FMT_MEM, }, - { 0x2400, "FSB", MIL_FMT_B, }, - { 0x4090, "FSBX", MIL_FMT_BX, }, - { 0xB900, "FSR", MIL_FMT_R, }, - { 0xA300, "INCM", MIL_FMT_IM_1_16, }, - { 0x7000, "JC", MIL_FMT_JUMP, }, - { 0x7100, "JCI", MIL_FMT_JUMP, }, - { 0x7200, "JS", MIL_FMT_MEM, }, - { 0x8300, "LISN", MIL_FMT_IS, }, - { 0x8000, "L", MIL_FMT_MEM, }, - { 0x0000, "LB", MIL_FMT_B, }, - { 0x4000, "LBX", MIL_FMT_BX, }, - { 0xDE00, "LE", MIL_FMT_MEM, }, - { 0x8400, "LI", MIL_FMT_MEM, }, - { 0x8500, "LIM", MIL_FMT_MEM, }, - { 0x8200, "LISP", MIL_FMT_IS, }, - { 0x8C00, "LLB", MIL_FMT_MEM, }, - { 0x8E00, "LLBI", MIL_FMT_MEM, }, - { 0x8900, "LM", MIL_FMT_IM_0_15, }, - { 0x8100, "LR", MIL_FMT_R, }, - { 0x7C00, "LSTI", MIL_FMT_ADDR, }, - { 0x7D00, "LST", MIL_FMT_ADDR, }, - { 0x8B00, "LUB", MIL_FMT_MEM, }, - { 0x8D00, "LUBI", MIL_FMT_MEM, }, - { 0xC500, "MR", MIL_FMT_R, }, - { 0xC400, "M", MIL_FMT_MEM, }, - { 0x1800, "MB", MIL_FMT_B, }, - { 0x4060, "MBX", MIL_FMT_BX, }, - { 0xC300, "MISN", MIL_FMT_IS, }, - { 0xC200, "MISP", MIL_FMT_IS, }, - { 0x4A03, "MIM", MIL_FMT_IM_OCX, }, - { 0x9300, "MOV", MIL_FMT_R, }, - { 0xC000, "MS", MIL_FMT_MEM, }, - { 0x4A04, "MSIM", MIL_FMT_IM_OCX, }, - { 0xC100, "MSR", MIL_FMT_R, }, - { 0xE600, "N", MIL_FMT_MEM, }, - { 0xB400, "NEG", MIL_FMT_R, }, - { 0x4A0B, "NIM", MIL_FMT_IM_OCX, }, - { 0xFF00, "NOP", MIL_FMT_NONE, }, - { 0xE700, "NR", MIL_FMT_R, }, - { 0xE000, "OR", MIL_FMT_MEM, }, - { 0x3000, "ORB", MIL_FMT_B, }, - { 0x40F0, "ORBX", MIL_FMT_BX, }, - { 0x4A08, "ORIM", MIL_FMT_IM_OCX, }, - { 0xE100, "ORR", MIL_FMT_R, }, - { 0x8F00, "POPM", MIL_FMT_R, }, - { 0x9F00, "PSHM", MIL_FMT_R, }, - { 0x5300, "RB", MIL_FMT_IM_0_15, }, - { 0x5500, "RBI", MIL_FMT_IM_0_15, }, - { 0x5400, "RBR", MIL_FMT_IMM_R, }, - { 0x5C00, "RVBR", MIL_FMT_R, }, - { 0x9E00, "SLBI", MIL_FMT_MEM, }, - { 0x4050, "SBBX", MIL_FMT_BX, }, - { 0x4020, "STBX", MIL_FMT_BX, }, - { 0x6C00, "SCR", MIL_FMT_R, }, - { 0x6B00, "SAR", MIL_FMT_R, }, - { 0xB000, "S", MIL_FMT_MEM, }, - { 0x5000, "SB", MIL_FMT_IM_0_15, }, - { 0x1400, "SBB", MIL_FMT_B, }, - { 0x5100, "SBR", MIL_FMT_IMM_R, }, - { 0x5200, "SBI", MIL_FMT_IM_0_15, }, - { 0x9500, "SFBS", MIL_FMT_R, }, - { 0x4A02, "SIM", MIL_FMT_IM_OCX, }, - { 0xB200, "SISP", MIL_FMT_IS, }, - { 0x7E00, "SJS", MIL_FMT_MEM, }, - { 0x6300, "SLC", MIL_FMT_R_IMM, }, - { 0x6000, "SLL", MIL_FMT_R_IMM, }, - { 0x6A00, "SLR", MIL_FMT_R, }, - { 0x7300, "SOJ", MIL_FMT_MEM, }, - { 0xB100, "SR", MIL_FMT_R, }, - { 0x6200, "SRA", MIL_FMT_R_IMM, }, - { 0x9700, "SRM", MIL_FMT_MEM, }, - { 0x6100, "SRL", MIL_FMT_R_IMM, }, - { 0x9000, "ST", MIL_FMT_MEM, }, - { 0x9100, "STC", MIL_FMT_IM_0_15, }, - { 0x9200, "STCI", MIL_FMT_IM_0_15, }, - { 0x9400, "STI", MIL_FMT_MEM, }, - { 0x0800, "STB", MIL_FMT_B, }, - { 0x9C00, "STLB", MIL_FMT_MEM, }, - { 0x9900, "STM", MIL_FMT_IM_0_15, }, - { 0x9B00, "STUB", MIL_FMT_MEM, }, - { 0x9D00, "SUBI", MIL_FMT_MEM, }, - { 0x5A00, "SVBR", MIL_FMT_R, }, - { 0x5600, "TB", MIL_FMT_IM_0_15, }, - { 0xDC00, "STE", MIL_FMT_MEM, }, - { 0x5700, "TBR", MIL_FMT_IMM_R, }, - { 0x5E00, "TVBR", MIL_FMT_R, }, - { 0x5800, "TBI", MIL_FMT_IM_0_15, }, - { 0x5900, "TSB", MIL_FMT_IM_0_15, }, - { 0xAE00, "UA", MIL_FMT_MEM, }, - { 0xAD00, "UAR", MIL_FMT_R, }, - { 0xFD00, "UC", MIL_FMT_MEM, }, - { 0xF500, "UCIM", MIL_FMT_IM_OCX, }, - { 0xFC00, "UCR", MIL_FMT_R, }, - { 0x7F00, "URS", MIL_FMT_SR, }, - { 0xBE00, "US", MIL_FMT_MEM, }, - { 0xBD00, "USR", MIL_FMT_R, }, - { 0x4900, "VIO", MIL_FMT_MEM, }, - { 0xEC00, "XBR", MIL_FMT_R, }, - { 0x4800, "XIO", MIL_FMT_XIO, }, - { 0xE400, "XOR", MIL_FMT_MEM, }, - { 0x4A09, "XORM", MIL_FMT_IM_OCX, }, - { 0xE500, "XORR", MIL_FMT_R, }, - { 0xED00, "XWR", MIL_FMT_R, }, + { MIL_OP_ABX, "ABX", MIL_FMT_BX }, + { MIL_OP_ANDX, "ANDX", MIL_FMT_BX }, + { MIL_OP_A, "A", MIL_FMT_MEM }, + { MIL_OP_ABS, "ABS", MIL_FMT_R }, + { MIL_OP_AIM, "AIM", MIL_FMT_IM_OCX }, + { MIL_OP_AISP, "AISP", MIL_FMT_IS }, + { MIL_OP_AND, "AND", MIL_FMT_MEM }, + { MIL_OP_ANDB, "ANDB", MIL_FMT_B }, + { MIL_OP_ANDM, "ANDM", MIL_FMT_IM_OCX }, + { MIL_OP_ANDR, "ANDR", MIL_FMT_R }, + { MIL_OP_AR, "AR", MIL_FMT_R }, + { MIL_OP_AB, "AB", MIL_FMT_B }, + { MIL_OP_BEX, "BEX", MIL_FMT_S }, + { MIL_OP_BEZ, "BEZ", MIL_FMT_ICR }, + { MIL_OP_BGE, "BGE", MIL_FMT_ICR }, + { MIL_OP_BGT, "BGT", MIL_FMT_ICR }, + { MIL_OP_BIF, "BIF", MIL_FMT_S }, + { MIL_OP_BLE, "BLE", MIL_FMT_ICR }, + { MIL_OP_BLT, "BLT", MIL_FMT_ICR }, + { MIL_OP_BNZ, "BNZ", MIL_FMT_ICR }, + { MIL_OP_BPT, "BPT", MIL_FMT_NONE }, + { MIL_OP_BR, "BR", MIL_FMT_ICR }, + { MIL_OP_C, "C", MIL_FMT_MEM }, + { MIL_OP_CB, "CB", MIL_FMT_B }, + { MIL_OP_CBL, "CBL", MIL_FMT_MEM }, + { MIL_OP_CBX, "CBX", MIL_FMT_BX }, + { MIL_OP_CR, "CR", MIL_FMT_R }, + { MIL_OP_CISP, "CISP", MIL_FMT_IS }, + { MIL_OP_CISN, "CISN", MIL_FMT_IS }, + { MIL_OP_CIM, "CIM", MIL_FMT_IM_OCX }, + { MIL_OP_DDR, "DDR", MIL_FMT_R }, + { MIL_OP_DD, "DD", MIL_FMT_MEM }, + { MIL_OP_D, "D", MIL_FMT_MEM }, + { MIL_OP_DA, "DA", MIL_FMT_MEM }, + { MIL_OP_DABS, "DABS", MIL_FMT_R }, + { MIL_OP_DAR, "DAR", MIL_FMT_R }, + { MIL_OP_DB, "DB", MIL_FMT_B }, + { MIL_OP_DC, "DC", MIL_FMT_MEM }, + { MIL_OP_DCR, "DCR", MIL_FMT_R }, + { MIL_OP_DECM, "DECM", MIL_FMT_IM_1_16 }, + { MIL_OP_DIM, "DIM", MIL_FMT_IM_OCX }, + { MIL_OP_DISN, "DISN", MIL_FMT_IS }, + { MIL_OP_DISP, "DISP", MIL_FMT_IS }, + { MIL_OP_DL, "DL", MIL_FMT_MEM }, + { MIL_OP_DLB, "DLB", MIL_FMT_B }, + { MIL_OP_DLBX, "DLBX", MIL_FMT_BX }, + { MIL_OP_DLE, "DLE", MIL_FMT_MEM }, + { MIL_OP_DLI, "DLI", MIL_FMT_MEM }, + { MIL_OP_DLR, "DLR", MIL_FMT_R }, + { MIL_OP_DM, "DM", MIL_FMT_MEM }, + { MIL_OP_DMR, "DMR", MIL_FMT_R }, + { MIL_OP_DNEG, "DNEG", MIL_FMT_R }, + { MIL_OP_DR, "DR", MIL_FMT_R }, + { MIL_OP_DS, "DS", MIL_FMT_MEM }, + { MIL_OP_DSAR, "DSAR", MIL_FMT_R }, + { MIL_OP_DSCR, "DSCR", MIL_FMT_R }, + { MIL_OP_DSLL, "DSLL", MIL_FMT_R_IMM }, + { MIL_OP_DSLC, "DSLC", MIL_FMT_R_IMM }, + { MIL_OP_DSLR, "DSLR", MIL_FMT_R }, + { MIL_OP_DSRA, "DSRA", MIL_FMT_R_IMM }, + { MIL_OP_DSRL, "DSRL", MIL_FMT_R_IMM }, + { MIL_OP_DSR, "DSR", MIL_FMT_R }, + { MIL_OP_DST, "DST", MIL_FMT_MEM }, + { MIL_OP_DSTB, "DSTB", MIL_FMT_B }, + { MIL_OP_DSTI, "DSTI", MIL_FMT_MEM }, + { MIL_OP_DSTE, "DSTE", MIL_FMT_MEM }, + { MIL_OP_DSTX, "DSTX", MIL_FMT_BX }, + { MIL_OP_DV, "DV", MIL_FMT_MEM }, + { MIL_OP_DVIM, "DVIM", MIL_FMT_IM_OCX }, + { MIL_OP_DVR, "DVR", MIL_FMT_R }, + { MIL_OP_DBX, "DBX", MIL_FMT_BX }, + { MIL_OP_EFLT, "EFLT", MIL_FMT_R }, + { MIL_OP_EFIX, "EFIX", MIL_FMT_R }, + { MIL_OP_EFC, "EFC", MIL_FMT_MEM }, + { MIL_OP_EFCR, "EFCR", MIL_FMT_R }, + { MIL_OP_EFA, "EFA", MIL_FMT_MEM }, + { MIL_OP_EFAR, "EFAR", MIL_FMT_R }, + { MIL_OP_EFD, "EFD", MIL_FMT_MEM }, + { MIL_OP_EFDR, "EFDR", MIL_FMT_R }, + { MIL_OP_EFL, "EFL", MIL_FMT_MEM }, + { MIL_OP_EFM, "EFM", MIL_FMT_MEM }, + { MIL_OP_EFMR, "EFMR", MIL_FMT_R }, + { MIL_OP_EFS, "EFS", MIL_FMT_MEM }, + { MIL_OP_EFSR, "EFSR", MIL_FMT_R }, + { MIL_OP_EFST, "EFST", MIL_FMT_MEM }, + { MIL_OP_FABS, "FABS", MIL_FMT_R }, + { MIL_OP_FA, "FA", MIL_FMT_MEM }, + { MIL_OP_FAB, "FAB", MIL_FMT_B }, + { MIL_OP_FABX, "FABX", MIL_FMT_BX }, + { MIL_OP_FAR, "FAR", MIL_FMT_R }, + { MIL_OP_FC, "FC", MIL_FMT_MEM }, + { MIL_OP_FCB, "FCB", MIL_FMT_B }, + { MIL_OP_FCBX, "FCBX", MIL_FMT_BX }, + { MIL_OP_FCR, "FCR", MIL_FMT_R }, + { MIL_OP_FD, "FD", MIL_FMT_MEM }, + { MIL_OP_FDB, "FDB", MIL_FMT_B }, + { MIL_OP_FDBX, "FDBX", MIL_FMT_BX }, + { MIL_OP_FDR, "FDR", MIL_FMT_R }, + { MIL_OP_FIX, "FIX", MIL_FMT_R }, + { MIL_OP_FLT, "FLT", MIL_FMT_R }, + { MIL_OP_FM, "FM", MIL_FMT_MEM }, + { MIL_OP_FMB, "FMB", MIL_FMT_B }, + { MIL_OP_FMBX, "FMBX", MIL_FMT_BX }, + { MIL_OP_FMR, "FMR", MIL_FMT_R }, + { MIL_OP_FNEG, "FNEG", MIL_FMT_R }, + { MIL_OP_FS, "FS", MIL_FMT_MEM }, + { MIL_OP_FSB, "FSB", MIL_FMT_B }, + { MIL_OP_FSBX, "FSBX", MIL_FMT_BX }, + { MIL_OP_FSR, "FSR", MIL_FMT_R }, + { MIL_OP_INCM, "INCM", MIL_FMT_IM_1_16 }, + { MIL_OP_JC, "JC", MIL_FMT_JUMP }, + { MIL_OP_JCI, "JCI", MIL_FMT_JUMP }, + { MIL_OP_JS, "JS", MIL_FMT_MEM }, + { MIL_OP_LISN, "LISN", MIL_FMT_IS }, + { MIL_OP_L, "L", MIL_FMT_MEM }, + { MIL_OP_LB, "LB", MIL_FMT_B }, + { MIL_OP_LBX, "LBX", MIL_FMT_BX }, + { MIL_OP_LE, "LE", MIL_FMT_MEM }, + { MIL_OP_LI, "LI", MIL_FMT_MEM }, + { MIL_OP_LIM, "LIM", MIL_FMT_MEM }, + { MIL_OP_LISP, "LISP", MIL_FMT_IS }, + { MIL_OP_LLB, "LLB", MIL_FMT_MEM }, + { MIL_OP_LLBI, "LLBI", MIL_FMT_MEM }, + { MIL_OP_LM, "LM", MIL_FMT_IM_0_15 }, + { MIL_OP_LR, "LR", MIL_FMT_R }, + { MIL_OP_LSTI, "LSTI", MIL_FMT_ADDR }, + { MIL_OP_LST, "LST", MIL_FMT_ADDR }, + { MIL_OP_LUB, "LUB", MIL_FMT_MEM }, + { MIL_OP_LUBI, "LUBI", MIL_FMT_MEM }, + { MIL_OP_MR, "MR", MIL_FMT_R }, + { MIL_OP_M, "M", MIL_FMT_MEM }, + { MIL_OP_MB, "MB", MIL_FMT_B }, + { MIL_OP_MBX, "MBX", MIL_FMT_BX }, + { MIL_OP_MISN, "MISN", MIL_FMT_IS }, + { MIL_OP_MISP, "MISP", MIL_FMT_IS }, + { MIL_OP_MIM, "MIM", MIL_FMT_IM_OCX }, + { MIL_OP_MOV, "MOV", MIL_FMT_R }, + { MIL_OP_MS, "MS", MIL_FMT_MEM }, + { MIL_OP_MSIM, "MSIM", MIL_FMT_IM_OCX }, + { MIL_OP_MSR, "MSR", MIL_FMT_R }, + { MIL_OP_N, "N", MIL_FMT_MEM }, + { MIL_OP_NEG, "NEG", MIL_FMT_R }, + { MIL_OP_NIM, "NIM", MIL_FMT_IM_OCX }, + { MIL_OP_NOP, "NOP", MIL_FMT_NONE }, + { MIL_OP_NR, "NR", MIL_FMT_R }, + { MIL_OP_OR, "OR", MIL_FMT_MEM }, + { MIL_OP_ORB, "ORB", MIL_FMT_B }, + { MIL_OP_ORBX, "ORBX", MIL_FMT_BX }, + { MIL_OP_ORIM, "ORIM", MIL_FMT_IM_OCX }, + { MIL_OP_ORR, "ORR", MIL_FMT_R }, + { MIL_OP_POPM, "POPM", MIL_FMT_R }, + { MIL_OP_PSHM, "PSHM", MIL_FMT_R }, + { MIL_OP_RB, "RB", MIL_FMT_IM_0_15 }, + { MIL_OP_RBI, "RBI", MIL_FMT_IM_0_15 }, + { MIL_OP_RBR, "RBR", MIL_FMT_IMM_R }, + { MIL_OP_RVBR, "RVBR", MIL_FMT_R }, + { MIL_OP_SLBI, "SLBI", MIL_FMT_MEM }, + { MIL_OP_SBBX, "SBBX", MIL_FMT_BX }, + { MIL_OP_STBX, "STBX", MIL_FMT_BX }, + { MIL_OP_SCR, "SCR", MIL_FMT_R }, + { MIL_OP_SAR, "SAR", MIL_FMT_R }, + { MIL_OP_S, "S", MIL_FMT_MEM }, + { MIL_OP_SB, "SB", MIL_FMT_IM_0_15 }, + { MIL_OP_SBB, "SBB", MIL_FMT_B }, + { MIL_OP_SBR, "SBR", MIL_FMT_IMM_R }, + { MIL_OP_SBI, "SBI", MIL_FMT_IM_0_15 }, + { MIL_OP_SFBS, "SFBS", MIL_FMT_R }, + { MIL_OP_SIM, "SIM", MIL_FMT_IM_OCX }, + { MIL_OP_SISP, "SISP", MIL_FMT_IS }, + { MIL_OP_SJS, "SJS", MIL_FMT_MEM }, + { MIL_OP_SLC, "SLC", MIL_FMT_R_IMM }, + { MIL_OP_SLL, "SLL", MIL_FMT_R_IMM }, + { MIL_OP_SLR, "SLR", MIL_FMT_R }, + { MIL_OP_SOJ, "SOJ", MIL_FMT_MEM }, + { MIL_OP_SR, "SR", MIL_FMT_R }, + { MIL_OP_SRA, "SRA", MIL_FMT_R_IMM }, + { MIL_OP_SRM, "SRM", MIL_FMT_MEM }, + { MIL_OP_SRL, "SRL", MIL_FMT_R_IMM }, + { MIL_OP_ST, "ST", MIL_FMT_MEM }, + { MIL_OP_STC, "STC", MIL_FMT_IM_0_15 }, + { MIL_OP_STCI, "STCI", MIL_FMT_IM_0_15 }, + { MIL_OP_STI, "STI", MIL_FMT_MEM }, + { MIL_OP_STB, "STB", MIL_FMT_B }, + { MIL_OP_STLB, "STLB", MIL_FMT_MEM }, + { MIL_OP_STM, "STM", MIL_FMT_IM_0_15 }, + { MIL_OP_STUB, "STUB", MIL_FMT_MEM }, + { MIL_OP_SUBI, "SUBI", MIL_FMT_MEM }, + { MIL_OP_SVBR, "SVBR", MIL_FMT_R }, + { MIL_OP_TB, "TB", MIL_FMT_IM_0_15 }, + { MIL_OP_STE, "STE", MIL_FMT_MEM }, + { MIL_OP_TBR, "TBR", MIL_FMT_IMM_R }, + { MIL_OP_TVBR, "TVBR", MIL_FMT_R }, + { MIL_OP_TBI, "TBI", MIL_FMT_IM_0_15 }, + { MIL_OP_TSB, "TSB", MIL_FMT_IM_0_15 }, + { MIL_OP_UA, "UA", MIL_FMT_MEM }, + { MIL_OP_UAR, "UAR", MIL_FMT_R }, + { MIL_OP_UC, "UC", MIL_FMT_MEM }, + { MIL_OP_UCIM, "UCIM", MIL_FMT_IM_OCX }, + { MIL_OP_UCR, "UCR", MIL_FMT_R }, + { MIL_OP_URS, "URS", MIL_FMT_SR }, + { MIL_OP_US, "US", MIL_FMT_MEM }, + { MIL_OP_USR, "USR", MIL_FMT_R }, + { MIL_OP_VIO, "VIO", MIL_FMT_MEM }, + { MIL_OP_XBR, "XBR", MIL_FMT_R }, + { MIL_OP_XIO, "XIO", MIL_FMT_XIO }, + { MIL_OP_XOR, "XOR", MIL_FMT_MEM }, + { MIL_OP_XORM, "XORM", MIL_FMT_IM_OCX }, + { MIL_OP_XORR, "XORR", MIL_FMT_R }, + { MIL_OP_XWR, "XWR", MIL_FMT_R }, }; // clang-format on @@ -438,8 +438,7 @@ bool rz_milstd1750_decode(const ut8 *buf, int len, MilStd1750Instruction *out) { out->mnemonic = m->mnemonic; out->format = m->format; out->size = size; - out->raw_w1 = w1; - out->raw_w2 = w2; + out->opcode = m->opcode; switch (m->format) { case MIL_FMT_NONE: diff --git a/librz/arch/isa/milstd1750/milstd1750_disas.h b/librz/arch/isa/milstd1750/milstd1750_disas.h index a78d30fb171..7810a0e3e58 100644 --- a/librz/arch/isa/milstd1750/milstd1750_disas.h +++ b/librz/arch/isa/milstd1750/milstd1750_disas.h @@ -5,6 +5,7 @@ #define RZ_MILSTD1750_DISAS_H #include +#include "opcodes.h" typedef enum { MIL_FMT_NONE, // no operands @@ -30,8 +31,7 @@ typedef struct { const char *mnemonic; MilStd1750Format format; ut8 size; // 2 or 4 (bytes) - ut16 raw_w1; - ut16 raw_w2; + ut16 opcode; // canonical opcode (a MIL_OP_* pattern): operand bits cleared // Decoded operand fields. Only those relevant to `format` are valid. ut8 ra; // R, SR, IS, XIO, MEM, IM_OCX diff --git a/librz/arch/isa/milstd1750/opcodes.h b/librz/arch/isa/milstd1750/opcodes.h new file mode 100644 index 00000000000..ed30ece0027 --- /dev/null +++ b/librz/arch/isa/milstd1750/opcodes.h @@ -0,0 +1,263 @@ +// SPDX-FileCopyrightText: 2026 godcodehunter +// SPDX-License-Identifier: LGPL-3.0-only + +#ifndef RZ_MILSTD1750_OPCODES_H +#define RZ_MILSTD1750_OPCODES_H + +// Full 16-bit opcode match patterns for MIL-STD-1750A instructions. The low +// byte is zero for one-word opcodes; IM-format (0x4A0x) and the special words +// (BPT/NOP) carry meaningful low bits. Shared between the disassembler table +// and the analysis plugin, which compares against the instruction word with its +// operand bits cleared. + +#define MIL_OP_LB 0x0000 +#define MIL_OP_DLB 0x0400 +#define MIL_OP_STB 0x0800 +#define MIL_OP_DSTB 0x0C00 +#define MIL_OP_AB 0x1000 +#define MIL_OP_SBB 0x1400 +#define MIL_OP_MB 0x1800 +#define MIL_OP_DB 0x1C00 +#define MIL_OP_FAB 0x2000 +#define MIL_OP_FSB 0x2400 +#define MIL_OP_FMB 0x2800 +#define MIL_OP_FDB 0x2C00 +#define MIL_OP_ORB 0x3000 +#define MIL_OP_ANDB 0x3400 +#define MIL_OP_CB 0x3800 +#define MIL_OP_FCB 0x3C00 +#define MIL_OP_LBX 0x4000 +#define MIL_OP_DLBX 0x4010 +#define MIL_OP_STBX 0x4020 +#define MIL_OP_DSTX 0x4030 +#define MIL_OP_ABX 0x4040 +#define MIL_OP_SBBX 0x4050 +#define MIL_OP_MBX 0x4060 +#define MIL_OP_DBX 0x4070 +#define MIL_OP_FABX 0x4080 +#define MIL_OP_FSBX 0x4090 +#define MIL_OP_FMBX 0x40A0 +#define MIL_OP_FDBX 0x40B0 +#define MIL_OP_CBX 0x40C0 +#define MIL_OP_FCBX 0x40D0 +#define MIL_OP_ANDX 0x40E0 +#define MIL_OP_ORBX 0x40F0 +#define MIL_OP_XIO 0x4800 +#define MIL_OP_VIO 0x4900 +#define MIL_OP_AIM 0x4A01 +#define MIL_OP_SIM 0x4A02 +#define MIL_OP_MIM 0x4A03 +#define MIL_OP_MSIM 0x4A04 +#define MIL_OP_DIM 0x4A05 +#define MIL_OP_DVIM 0x4A06 +#define MIL_OP_ANDM 0x4A07 +#define MIL_OP_ORIM 0x4A08 +#define MIL_OP_XORM 0x4A09 +#define MIL_OP_CIM 0x4A0A +#define MIL_OP_NIM 0x4A0B +#define MIL_OP_BIF 0x4F00 +#define MIL_OP_SB 0x5000 +#define MIL_OP_SBR 0x5100 +#define MIL_OP_SBI 0x5200 +#define MIL_OP_RB 0x5300 +#define MIL_OP_RBR 0x5400 +#define MIL_OP_RBI 0x5500 +#define MIL_OP_TB 0x5600 +#define MIL_OP_TBR 0x5700 +#define MIL_OP_TBI 0x5800 +#define MIL_OP_TSB 0x5900 +#define MIL_OP_SVBR 0x5A00 +#define MIL_OP_RVBR 0x5C00 +#define MIL_OP_TVBR 0x5E00 +#define MIL_OP_SLL 0x6000 +#define MIL_OP_SRL 0x6100 +#define MIL_OP_SRA 0x6200 +#define MIL_OP_SLC 0x6300 +#define MIL_OP_DSLL 0x6500 +#define MIL_OP_DSRL 0x6600 +#define MIL_OP_DSRA 0x6700 +#define MIL_OP_DSLC 0x6800 +#define MIL_OP_SLR 0x6A00 +#define MIL_OP_SAR 0x6B00 +#define MIL_OP_SCR 0x6C00 +#define MIL_OP_DSLR 0x6D00 +#define MIL_OP_DSAR 0x6E00 +#define MIL_OP_DSCR 0x6F00 +#define MIL_OP_JC 0x7000 +#define MIL_OP_JCI 0x7100 +#define MIL_OP_JS 0x7200 +#define MIL_OP_SOJ 0x7300 +#define MIL_OP_BR 0x7400 +#define MIL_OP_BEZ 0x7500 +#define MIL_OP_BLT 0x7600 +#define MIL_OP_BEX 0x7700 +#define MIL_OP_BLE 0x7800 +#define MIL_OP_BGT 0x7900 +#define MIL_OP_BNZ 0x7A00 +#define MIL_OP_BGE 0x7B00 +#define MIL_OP_LSTI 0x7C00 +#define MIL_OP_LST 0x7D00 +#define MIL_OP_SJS 0x7E00 +#define MIL_OP_URS 0x7F00 +#define MIL_OP_L 0x8000 +#define MIL_OP_LR 0x8100 +#define MIL_OP_LISP 0x8200 +#define MIL_OP_LISN 0x8300 +#define MIL_OP_LI 0x8400 +#define MIL_OP_LIM 0x8500 +#define MIL_OP_DL 0x8600 +#define MIL_OP_DLR 0x8700 +#define MIL_OP_DLI 0x8800 +#define MIL_OP_LM 0x8900 +#define MIL_OP_EFL 0x8A00 +#define MIL_OP_LUB 0x8B00 +#define MIL_OP_LLB 0x8C00 +#define MIL_OP_LUBI 0x8D00 +#define MIL_OP_LLBI 0x8E00 +#define MIL_OP_POPM 0x8F00 +#define MIL_OP_ST 0x9000 +#define MIL_OP_STC 0x9100 +#define MIL_OP_STCI 0x9200 +#define MIL_OP_MOV 0x9300 +#define MIL_OP_STI 0x9400 +#define MIL_OP_SFBS 0x9500 +#define MIL_OP_DST 0x9600 +#define MIL_OP_SRM 0x9700 +#define MIL_OP_DSTI 0x9800 +#define MIL_OP_STM 0x9900 +#define MIL_OP_EFST 0x9A00 +#define MIL_OP_STUB 0x9B00 +#define MIL_OP_STLB 0x9C00 +#define MIL_OP_SUBI 0x9D00 +#define MIL_OP_SLBI 0x9E00 +#define MIL_OP_PSHM 0x9F00 +#define MIL_OP_A 0xA000 +#define MIL_OP_AR 0xA100 +#define MIL_OP_AISP 0xA200 +#define MIL_OP_INCM 0xA300 +#define MIL_OP_ABS 0xA400 +#define MIL_OP_DABS 0xA500 +#define MIL_OP_DA 0xA600 +#define MIL_OP_DAR 0xA700 +#define MIL_OP_FA 0xA800 +#define MIL_OP_FAR 0xA900 +#define MIL_OP_EFA 0xAA00 +#define MIL_OP_EFAR 0xAB00 +#define MIL_OP_FABS 0xAC00 +#define MIL_OP_UAR 0xAD00 +#define MIL_OP_UA 0xAE00 +#define MIL_OP_S 0xB000 +#define MIL_OP_SR 0xB100 +#define MIL_OP_SISP 0xB200 +#define MIL_OP_DECM 0xB300 +#define MIL_OP_NEG 0xB400 +#define MIL_OP_DNEG 0xB500 +#define MIL_OP_DS 0xB600 +#define MIL_OP_DSR 0xB700 +#define MIL_OP_FS 0xB800 +#define MIL_OP_FSR 0xB900 +#define MIL_OP_EFS 0xBA00 +#define MIL_OP_EFSR 0xBB00 +#define MIL_OP_FNEG 0xBC00 +#define MIL_OP_USR 0xBD00 +#define MIL_OP_US 0xBE00 +#define MIL_OP_MS 0xC000 +#define MIL_OP_MSR 0xC100 +#define MIL_OP_MISP 0xC200 +#define MIL_OP_MISN 0xC300 +#define MIL_OP_M 0xC400 +#define MIL_OP_MR 0xC500 +#define MIL_OP_DM 0xC600 +#define MIL_OP_DMR 0xC700 +#define MIL_OP_FM 0xC800 +#define MIL_OP_FMR 0xC900 +#define MIL_OP_EFM 0xCA00 +#define MIL_OP_EFMR 0xCB00 +#define MIL_OP_DV 0xD000 +#define MIL_OP_DVR 0xD100 +#define MIL_OP_DISP 0xD200 +#define MIL_OP_DISN 0xD300 +#define MIL_OP_D 0xD400 +#define MIL_OP_DR 0xD500 +#define MIL_OP_DD 0xD600 +#define MIL_OP_DDR 0xD700 +#define MIL_OP_FD 0xD800 +#define MIL_OP_FDR 0xD900 +#define MIL_OP_EFD 0xDA00 +#define MIL_OP_EFDR 0xDB00 +#define MIL_OP_STE 0xDC00 +#define MIL_OP_DSTE 0xDD00 +#define MIL_OP_LE 0xDE00 +#define MIL_OP_DLE 0xDF00 +#define MIL_OP_OR 0xE000 +#define MIL_OP_ORR 0xE100 +#define MIL_OP_AND 0xE200 +#define MIL_OP_ANDR 0xE300 +#define MIL_OP_XOR 0xE400 +#define MIL_OP_XORR 0xE500 +#define MIL_OP_N 0xE600 +#define MIL_OP_NR 0xE700 +#define MIL_OP_FIX 0xE800 +#define MIL_OP_FLT 0xE900 +#define MIL_OP_EFIX 0xEA00 +#define MIL_OP_EFLT 0xEB00 +#define MIL_OP_XBR 0xEC00 +#define MIL_OP_XWR 0xED00 +#define MIL_OP_C 0xF000 +#define MIL_OP_CR 0xF100 +#define MIL_OP_CISP 0xF200 +#define MIL_OP_CISN 0xF300 +#define MIL_OP_CBL 0xF400 +#define MIL_OP_UCIM 0xF500 +#define MIL_OP_DC 0xF600 +#define MIL_OP_DCR 0xF700 +#define MIL_OP_FC 0xF800 +#define MIL_OP_FCR 0xF900 +#define MIL_OP_EFC 0xFA00 +#define MIL_OP_EFCR 0xFB00 +#define MIL_OP_UCR 0xFC00 +#define MIL_OP_UC 0xFD00 +#define MIL_OP_NOP 0xFF00 +#define MIL_OP_BPT 0xFFFF + +// XIO command words (second operand of XIO/VIO). + +#define MIL_XIO_SMK 0x2000 +#define MIL_XIO_CLIR 0x2001 +#define MIL_XIO_ENBL 0x2002 +#define MIL_XIO_DSBL 0x2003 +#define MIL_XIO_RPI 0x2004 +#define MIL_XIO_SPI 0x2005 +#define MIL_XIO_OD 0x2008 +#define MIL_XIO_RNS 0x200A +#define MIL_XIO_WSW 0x200E +#define MIL_XIO_CO 0x4000 +#define MIL_XIO_CLC 0x4001 +#define MIL_XIO_MPEN 0x4003 +#define MIL_XIO_ESUR 0x4004 +#define MIL_XIO_DSUR 0x4005 +#define MIL_XIO_DMAE 0x4006 +#define MIL_XIO_DMAD 0x4007 +#define MIL_XIO_TAS 0x4008 +#define MIL_XIO_TAH 0x4009 +#define MIL_XIO_OTA 0x400A +#define MIL_XIO_GO 0x400B +#define MIL_XIO_TBS 0x400C +#define MIL_XIO_TBH 0x400D +#define MIL_XIO_OTB 0x400E +#define MIL_XIO_RMK 0xA000 +#define MIL_XIO_RIC1 0xA001 +#define MIL_XIO_RIC2 0xA002 +#define MIL_XIO_RPIR 0xA004 +#define MIL_XIO_RDOR 0xA008 +#define MIL_XIO_RDI 0xA009 +#define MIL_XIO_TPIO 0xA00B +#define MIL_XIO_RMFS 0xA00D +#define MIL_XIO_RSW 0xA00E +#define MIL_XIO_RCFR 0xA00F +#define MIL_XIO_CI 0xC000 +#define MIL_XIO_RCS 0xC001 +#define MIL_XIO_ITA 0xC00A +#define MIL_XIO_ITB 0xC00E + +#endif diff --git a/librz/arch/p/analysis/analysis_milstd1750.c b/librz/arch/p/analysis/analysis_milstd1750.c index 82c8a046036..2a451fc9d5c 100644 --- a/librz/arch/p/analysis/analysis_milstd1750.c +++ b/librz/arch/p/analysis/analysis_milstd1750.c @@ -5,6 +5,611 @@ #include #include +// Reference: MIL-STD-1750A Military Standard Sixteen-Bit +// Computer Instruction Set Architecture +// Section 5.24 Jump on condition +static RzTypeCond jc_cond_to_type(ut8 cc) { + switch (cc & 0xF) { + case 0x1: return RZ_TYPE_COND_LT; + case 0x2: return RZ_TYPE_COND_EQ; + case 0x3: return RZ_TYPE_COND_LE; + case 0x4: return RZ_TYPE_COND_GT; + case 0x5: return RZ_TYPE_COND_NE; + case 0x6: return RZ_TYPE_COND_GE; + case 0x8: return RZ_TYPE_COND_HS; + case 0x9: return RZ_TYPE_COND_LT; //< carry or LT + case 0xA: return RZ_TYPE_COND_EQ; //< carry or EQ + case 0xB: return RZ_TYPE_COND_LE; //< carry or LE + case 0xC: return RZ_TYPE_COND_GT; //< carry or GT + case 0xD: return RZ_TYPE_COND_NE; //< carry or NE + case 0xE: return RZ_TYPE_COND_GE; //< carry or GE + default: return RZ_TYPE_COND_AL; + } +} + +static const char *milstd_reg_name(ut8 n) { + static const char *const regs[16] = { + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" + }; + return regs[n & 0xF]; +} + +// True for instruction formats that reference memory (as opposed to +// register-only or immediate forms). Used to decide whether a data-processing +// op actually touches memory. +static bool milstd_format_mem(MilStd1750Format f) { + switch (f) { + case MIL_FMT_MEM: + case MIL_FMT_B: + case MIL_FMT_BX: + case MIL_FMT_ADDR: + case MIL_FMT_IM_0_15: + case MIL_FMT_IM_1_16: + return true; + default: + return false; + } +} + +// Set op->direction (READ/WRITE/EXEC) from the resolved type and addressing +// format. MIL-STD-1750 is memory-oriented: arithmetic/compare may take a memory +// source operand (READ), and the in-memory bit/increment ops are +// read-modify-write (READ|WRITE). Register/immediate forms touch no memory. +static void milstd_set_direction(RzAnalysisOp *op, MilStd1750Format fmt) { + switch (op->type & RZ_ANALYSIS_OP_TYPE_MASK) { + case RZ_ANALYSIS_OP_TYPE_LOAD: + case RZ_ANALYSIS_OP_TYPE_POP: // POPM reads from the stack + op->direction = RZ_ANALYSIS_OP_DIR_READ; + break; + case RZ_ANALYSIS_OP_TYPE_STORE: + case RZ_ANALYSIS_OP_TYPE_PUSH: // PSHM writes to the stack + op->direction = RZ_ANALYSIS_OP_DIR_WRITE; + break; + case RZ_ANALYSIS_OP_TYPE_JMP: + case RZ_ANALYSIS_OP_TYPE_CJMP: + case RZ_ANALYSIS_OP_TYPE_CALL: + case RZ_ANALYSIS_OP_TYPE_UCALL: + case RZ_ANALYSIS_OP_TYPE_MJMP: + case RZ_ANALYSIS_OP_TYPE_MCJMP: + case RZ_ANALYSIS_OP_TYPE_RET: + op->direction = RZ_ANALYSIS_OP_DIR_EXEC; + break; + case RZ_ANALYSIS_OP_TYPE_ADD: + case RZ_ANALYSIS_OP_TYPE_SUB: + case RZ_ANALYSIS_OP_TYPE_MUL: + case RZ_ANALYSIS_OP_TYPE_DIV: + case RZ_ANALYSIS_OP_TYPE_AND: + case RZ_ANALYSIS_OP_TYPE_OR: + case RZ_ANALYSIS_OP_TYPE_XOR: + case RZ_ANALYSIS_OP_TYPE_NOT: + if (fmt == MIL_FMT_IM_0_15 || fmt == MIL_FMT_IM_1_16) { + // in-memory bit set/reset and INCM/DECM: the memory word is both + // source and destination + op->direction = RZ_ANALYSIS_OP_DIR_READ | RZ_ANALYSIS_OP_DIR_WRITE; + } else if (milstd_format_mem(fmt)) { + // memory operand read into the accumulator (e.g. A/S/AND ADDR) + op->direction = RZ_ANALYSIS_OP_DIR_READ; + } + break; + case RZ_ANALYSIS_OP_TYPE_CMP: + if (milstd_format_mem(fmt)) { + op->direction = RZ_ANALYSIS_OP_DIR_READ; + } + break; + default: + break; + } +} + +// Set op->val to the instruction's immediate operand, where one is encoded. +// The B/ICR displacement fields describe branch/data targets rather than data +// values and are deliberately left out (they surface via op->jump instead). +static void milstd_set_val(RzAnalysisOp *op, const MilStd1750Instruction *insn) { + switch (insn->format) { + case MIL_FMT_IS: // Ra, short immediate (1..16) + case MIL_FMT_IMM_R: // 4-bit immediate, Rb + case MIL_FMT_R_IMM: // Rb, immediate (incl. shift counts) + case MIL_FMT_IM_0_15: // bit index / register count + case MIL_FMT_IM_1_16: // INCM/DECM count + op->val = insn->imm8; + break; + case MIL_FMT_IM_OCX: // 16-bit immediate (AIM/SIM/.../CIM) + op->val = insn->imm16; + break; + case MIL_FMT_XIO: // 16-bit I/O command word + op->val = insn->xio_cmd; + break; + default: + break; + } +} + +// Memory-operand data width in bytes for a memory-format opcode (op->ptrsize). +static int milstd_mem_size(ut16 opc) { + switch (opc) { + // extended floating, 48-bit + case MIL_OP_EFL: + case MIL_OP_EFA: + case MIL_OP_EFS: + case MIL_OP_EFM: + case MIL_OP_EFD: + case MIL_OP_EFC: + case MIL_OP_EFST: + return 6; + // double-precision integer and single floating, 32-bit + case MIL_OP_DL: + case MIL_OP_DLI: + case MIL_OP_DLE: + case MIL_OP_DST: + case MIL_OP_DSTI: + case MIL_OP_DSTE: + case MIL_OP_DA: + case MIL_OP_DS: + case MIL_OP_DM: + case MIL_OP_DD: + case MIL_OP_DC: + case MIL_OP_FA: + case MIL_OP_FS: + case MIL_OP_FM: + case MIL_OP_FD: + case MIL_OP_FC: + // ... and their base-relative (B) and base-relative-indexed (BX) forms + case MIL_OP_DLB: + case MIL_OP_DLBX: + case MIL_OP_DSTB: + case MIL_OP_DSTX: + case MIL_OP_FAB: + case MIL_OP_FABX: + case MIL_OP_FSB: + case MIL_OP_FSBX: + case MIL_OP_FMB: + case MIL_OP_FMBX: + case MIL_OP_FDB: + case MIL_OP_FDBX: + case MIL_OP_FCB: + case MIL_OP_FCBX: + return 4; + // byte operand, 8-bit + case MIL_OP_LUB: + case MIL_OP_LLB: + case MIL_OP_LUBI: + case MIL_OP_LLBI: + case MIL_OP_STUB: + case MIL_OP_STLB: + case MIL_OP_SUBI: + case MIL_OP_SLBI: + return 1; + default: + return 2; // single word (16-bit) + } +} + +// Set op->ptr / op->ptrsize for instructions that statically reference memory +// via a direct address word. 1750 encodes word indices, so the byte address is +// addr*2. op->refptr is intentionally left 0 (ptr is a direct reference): the +// indirect *I forms hold a word-indexed pointer that the byte-oriented refptr +// auto-follow would misread, so indirection is not resolved here. +static void milstd_set_ptr(RzAnalysisOp *op, const MilStd1750Instruction *insn) { + switch (insn->format) { + case MIL_FMT_MEM: + case MIL_FMT_IM_0_15: + case MIL_FMT_IM_1_16: + break; + default: + return; // no direct address field (register/immediate/base-relative) + } + if (insn->opcode == MIL_OP_LIM) { + return; // LIM: the second word is an immediate value, not an address + } + switch (op->type & RZ_ANALYSIS_OP_TYPE_MASK) { + case RZ_ANALYSIS_OP_TYPE_JMP: + case RZ_ANALYSIS_OP_TYPE_CJMP: + case RZ_ANALYSIS_OP_TYPE_CALL: + case RZ_ANALYSIS_OP_TYPE_UCALL: + case RZ_ANALYSIS_OP_TYPE_MJMP: + case RZ_ANALYSIS_OP_TYPE_MCJMP: + case RZ_ANALYSIS_OP_TYPE_RET: + return; // JS/SJS/SOJ: addr is a code target (op->jump), not data + default: + break; + } + op->ptr = (ut64)insn->addr * 2; + op->ptrsize = milstd_mem_size(insn->opcode); +} + +// Set op->datatype: floating-point for F* (single, 32-bit) and EF* (extended, +// 48-bit) ops, otherwise the integer width of the memory operand. +static void milstd_set_datatype(RzAnalysisOp *op, const MilStd1750Instruction *insn) { + const char *m = insn->mnemonic; + if (m && (m[0] == 'F' || (m[0] == 'E' && m[1] == 'F'))) { + op->datatype = RZ_ANALYSIS_DATATYPE_FLOAT; + return; + } + switch (op->ptrsize) { + case 2: op->datatype = RZ_ANALYSIS_DATATYPE_INT16; break; + case 4: op->datatype = RZ_ANALYSIS_DATATYPE_INT32; break; + default: break; // byte (1) or no memory operand (0): leave NULL + } +} + +// Set op->stackop / op->stackptr for the stack instructions. Per MIL-STD-1750A +// R15 is the implicit stack pointer and the stack grows toward lower addresses, +// matching rizin's convention (RZ_ANALYSIS_STACK_INC applies sp -= stackptr, so +// a positive stackptr means the stack grows). Each register is one 16-bit word; +// stackptr is expressed in bytes to match the plugin's byte-addressed model. +static void milstd_set_stack(RzAnalysisOp *op, const MilStd1750Instruction *insn) { + switch (insn->opcode) { + // PSHM/POPM transfer the inclusive register range Ra..Rb, wrapping the + // register selector modulo 16 (so Ra > Rb pushes Ra..R15, R0..Rb). The + // count is therefore ((Rb - Ra) mod 16) + 1, always 1..16. + case MIL_OP_PSHM: { // PSHM Ra, Rb — push registers (SP grows) + int count = ((insn->rb - insn->ra) & 0xF) + 1; + op->stackop = RZ_ANALYSIS_STACK_INC; + op->stackptr = count * 2; + break; + } + case MIL_OP_POPM: { // POPM Ra, Rb — pop registers (SP shrinks) + int count = ((insn->rb - insn->ra) & 0xF) + 1; + op->stackop = RZ_ANALYSIS_STACK_INC; + op->stackptr = -count * 2; + break; + } + case MIL_OP_SJS: // SJS — stack the IC and jump (push one word) + op->stackop = RZ_ANALYSIS_STACK_INC; + op->stackptr = 2; + break; + case MIL_OP_URS: // URS — unstack the IC and return (pop one word) + op->stackop = RZ_ANALYSIS_STACK_INC; + op->stackptr = -2; + break; + default: + break; + } +} + +// Set op->reg (destination register) and op->ireg (register used to compute a +// memory effective address). Driven by the addressing format; op->type filters +// out instructions that have no register destination. +static void milstd_set_reg(RzAnalysisOp *op, const MilStd1750Instruction *insn) { + // Index / base register of the effective-address computation. + switch (insn->format) { + case MIL_FMT_MEM: + case MIL_FMT_IM_0_15: + case MIL_FMT_IM_1_16: + case MIL_FMT_ADDR: + if (insn->rx) { // Rx == 0 means no indexing + op->ireg = milstd_reg_name(insn->rx); + } + break; + case MIL_FMT_BX: // base-relative indexed: base R(br), index Rx + op->ireg = milstd_reg_name(insn->rx ? insn->rx : insn->br); + break; + case MIL_FMT_B: // base-relative: address computed from base register + op->ireg = milstd_reg_name(insn->br); + break; + default: + break; + } + + // Destination register: Ra for the Ra-based forms, Rb for the immediate + // forms (IMM_R/R_IMM, e.g. shifts and register bit ops). + const char *dst = NULL; + switch (insn->format) { + case MIL_FMT_R: + case MIL_FMT_SR: + case MIL_FMT_IS: + case MIL_FMT_IM_OCX: + case MIL_FMT_MEM: + dst = milstd_reg_name(insn->ra); + break; + case MIL_FMT_IMM_R: + case MIL_FMT_R_IMM: + dst = milstd_reg_name(insn->rb); + break; + default: + break; + } + // Drop it for ops with no register destination: compares, stores (memory is + // the destination), the multi-register stack ops, and control flow. + switch (op->type & RZ_ANALYSIS_OP_TYPE_MASK) { + case RZ_ANALYSIS_OP_TYPE_CMP: + case RZ_ANALYSIS_OP_TYPE_STORE: + case RZ_ANALYSIS_OP_TYPE_PUSH: + case RZ_ANALYSIS_OP_TYPE_POP: + case RZ_ANALYSIS_OP_TYPE_JMP: + case RZ_ANALYSIS_OP_TYPE_CJMP: + case RZ_ANALYSIS_OP_TYPE_CALL: + case RZ_ANALYSIS_OP_TYPE_UCALL: + case RZ_ANALYSIS_OP_TYPE_MJMP: + case RZ_ANALYSIS_OP_TYPE_MCJMP: + case RZ_ANALYSIS_OP_TYPE_RET: + dst = NULL; + break; + default: + break; + } + op->reg = dst; +} + +// --- RzAnalysisValue constructors (RZ_ANALYSIS_OP_MASK_VAL) --- +// RzAnalysisValue holds no owned sub-allocations (RzRegItem* are borrowed from +// the reg profile), so it is freed with plain free() and copied shallowly. + +static RzAnalysisValue *milstd_v_reg(RzAnalysis *a, ut8 n, RzAnalysisValueAccess acc) { + RzAnalysisValue *v = rz_analysis_value_new(); + if (!v) { + return NULL; + } + + v->type = RZ_ANALYSIS_VAL_REG; + v->access = acc; + v->reg = rz_reg_get(a->reg, milstd_reg_name(n), RZ_REG_TYPE_ANY); + + return v; +} + +static RzAnalysisValue *milstd_v_imm(st64 imm) { + RzAnalysisValue *v = rz_analysis_value_new(); + if (!v) { + return NULL; + } + + v->type = RZ_ANALYSIS_VAL_IMM; + v->access = RZ_ANALYSIS_ACC_R; + v->imm = imm; + + return v; +} + +// Direct memory operand: byte address `base` plus optional word index Rx. +static RzAnalysisValue *milstd_v_mem(RzAnalysis *a, ut64 base, ut8 rx, int memref, RzAnalysisValueAccess acc) { + RzAnalysisValue *v = rz_analysis_value_new(); + if (!v) { + return NULL; + } + + v->type = RZ_ANALYSIS_VAL_MEM; + v->access = acc; + v->memref = memref; + v->base = base; + if (rx) { + v->regdelta = rz_reg_get(a->reg, milstd_reg_name(rx), RZ_REG_TYPE_ANY); + v->mul = 2; // index counts 16-bit words + } + + return v; +} + +// Base-relative memory operand: base register R(br) + index Rx (BX) or disp (B). +static RzAnalysisValue *milstd_v_basemem(RzAnalysis *a, ut8 br, ut8 rx, st64 disp, int memref, RzAnalysisValueAccess acc) { + RzAnalysisValue *v = rz_analysis_value_new(); + if (!v) { + return NULL; + } + + v->type = RZ_ANALYSIS_VAL_MEM; + v->access = acc; + v->memref = memref; + v->reg = rz_reg_get(a->reg, milstd_reg_name(br), RZ_REG_TYPE_ANY); + v->delta = disp; + if (rx) { + v->regdelta = rz_reg_get(a->reg, milstd_reg_name(rx), RZ_REG_TYPE_ANY); + v->mul = 1; // base-relative index is added unscaled + } + + return v; +} + +// --- Operand-shape combinators ------------------------------------------ + +// Ra = Rb +static void milstd_reg_reg(RzAnalysis *a, RzAnalysisOp *op, ut8 rd, ut8 rs) { + op->dst = milstd_v_reg(a, rd, RZ_ANALYSIS_ACC_W); + op->src[0] = milstd_v_reg(a, rs, RZ_ANALYSIS_ACC_R); +} + +// Ra = imm +static void milstd_reg_imm(RzAnalysis *a, RzAnalysisOp *op, ut8 rd, st64 imm) { + op->dst = milstd_v_reg(a, rd, RZ_ANALYSIS_ACC_W); + op->src[0] = milstd_v_imm(imm); +} + +// Ra = [mem] +static void milstd_reg_mem(RzAnalysis *a, RzAnalysisOp *op, ut8 rd, RzAnalysisValue *mem) { + op->dst = milstd_v_reg(a, rd, RZ_ANALYSIS_ACC_W); + op->src[0] = mem; +} + +// [mem] = Ra +static void milstd_mem_reg(RzAnalysis *a, RzAnalysisOp *op, RzAnalysisValue *mem, ut8 rs) { + op->dst = mem; + op->src[0] = milstd_v_reg(a, rs, RZ_ANALYSIS_ACC_R); +} + +// [mem] = imm (store, or read-modify-write when the mem value carries ACC_R|ACC_W) +static void milstd_mem_imm(RzAnalysisOp *op, RzAnalysisValue *mem, st64 imm) { + op->dst = mem; + op->src[0] = milstd_v_imm(imm); +} + +// Ra = Ra (op) Rb +static void milstd_acc_reg(RzAnalysis *a, RzAnalysisOp *op, ut8 ra, ut8 rb) { + op->dst = milstd_v_reg(a, ra, RZ_ANALYSIS_ACC_W); + op->src[0] = milstd_v_reg(a, ra, RZ_ANALYSIS_ACC_R); + op->src[1] = milstd_v_reg(a, rb, RZ_ANALYSIS_ACC_R); +} + +// Ra = Ra (op) imm +static void milstd_acc_imm(RzAnalysis *a, RzAnalysisOp *op, ut8 ra, st64 imm) { + op->dst = milstd_v_reg(a, ra, RZ_ANALYSIS_ACC_W); + op->src[0] = milstd_v_reg(a, ra, RZ_ANALYSIS_ACC_R); + op->src[1] = milstd_v_imm(imm); +} + +// Ra = Ra (op) [mem] +static void milstd_acc_mem(RzAnalysis *a, RzAnalysisOp *op, ut8 ra, RzAnalysisValue *mem) { + op->dst = milstd_v_reg(a, ra, RZ_ANALYSIS_ACC_W); + op->src[0] = milstd_v_reg(a, ra, RZ_ANALYSIS_ACC_R); + op->src[1] = mem; +} + +// cmp Ra, Rb (two read sources, no destination) +static void milstd_cmp_reg_reg(RzAnalysis *a, RzAnalysisOp *op, ut8 r0, ut8 r1) { + op->src[0] = milstd_v_reg(a, r0, RZ_ANALYSIS_ACC_R); + op->src[1] = milstd_v_reg(a, r1, RZ_ANALYSIS_ACC_R); +} + +// cmp Ra, imm +static void milstd_cmp_reg_imm(RzAnalysis *a, RzAnalysisOp *op, ut8 r, st64 imm) { + op->src[0] = milstd_v_reg(a, r, RZ_ANALYSIS_ACC_R); + op->src[1] = milstd_v_imm(imm); +} + +// cmp Ra, [mem] +static void milstd_cmp_reg_mem(RzAnalysis *a, RzAnalysisOp *op, ut8 r, RzAnalysisValue *mem) { + op->src[0] = milstd_v_reg(a, r, RZ_ANALYSIS_ACC_R); + op->src[1] = mem; +} + +// cmp [mem], imm (test bit in memory) +static void milstd_cmp_mem_imm(RzAnalysisOp *op, RzAnalysisValue *mem, st64 imm) { + op->src[0] = mem; + op->src[1] = milstd_v_imm(imm); +} + +// Fill op->src[]/op->dst (analyzable operands) and op->access (flat read/write +// list). Driven by addressing format; op->type selects the read/write roles. +static void milstd_fill_val(RzAnalysis *a, RzAnalysisOp *op, const MilStd1750Instruction *insn) { + ut32 type = op->type & RZ_ANALYSIS_OP_TYPE_MASK; + int sz = milstd_mem_size(insn->opcode); + + switch (insn->format) { + case MIL_FMT_R: + if (type == RZ_ANALYSIS_OP_TYPE_PUSH || type == RZ_ANALYSIS_OP_TYPE_POP) { + break; // PSHM/POPM: operands are a register range, not modelled + } + if (type == RZ_ANALYSIS_OP_TYPE_CMP) { + milstd_cmp_reg_reg(a, op, insn->ra, insn->rb); + } else if (type == RZ_ANALYSIS_OP_TYPE_LOAD) { + milstd_reg_reg(a, op, insn->ra, insn->rb); // LR: Ra = Rb + } else { + milstd_acc_reg(a, op, insn->ra, insn->rb); // Ra = Ra (op) Rb + } + break; + case MIL_FMT_SR: + milstd_reg_reg(a, op, insn->ra, insn->ra); // Ra = (op) Ra + break; + case MIL_FMT_IS: + if (type == RZ_ANALYSIS_OP_TYPE_LOAD) { + milstd_reg_imm(a, op, insn->ra, insn->imm8); + } else if (type == RZ_ANALYSIS_OP_TYPE_CMP) { + milstd_cmp_reg_imm(a, op, insn->ra, insn->imm8); + } else { + milstd_acc_imm(a, op, insn->ra, insn->imm8); + } + break; + case MIL_FMT_IMM_R: + case MIL_FMT_R_IMM: + if (type == RZ_ANALYSIS_OP_TYPE_CMP) { + milstd_cmp_reg_imm(a, op, insn->rb, insn->imm8); + } else { + milstd_acc_imm(a, op, insn->rb, insn->imm8); + } + break; + case MIL_FMT_IM_OCX: + if (type == RZ_ANALYSIS_OP_TYPE_CMP) { + milstd_cmp_reg_imm(a, op, insn->ra, insn->imm16); + } else { + milstd_acc_imm(a, op, insn->ra, insn->imm16); + } + break; + case MIL_FMT_MEM: { + if (type == RZ_ANALYSIS_OP_TYPE_CALL || type == RZ_ANALYSIS_OP_TYPE_CJMP) { + break; // JS/SJS/SOJ: addr is a code target, not a data operand + } + if (insn->opcode == MIL_OP_LIM) { // LIM: the second word is an immediate, not memory + milstd_reg_imm(a, op, insn->ra, insn->addr); + break; + } + ut64 ea = (ut64)insn->addr * 2; + if (type == RZ_ANALYSIS_OP_TYPE_LOAD) { + milstd_reg_mem(a, op, insn->ra, milstd_v_mem(a, ea, insn->rx, sz, RZ_ANALYSIS_ACC_R)); + } else if (type == RZ_ANALYSIS_OP_TYPE_STORE) { + milstd_mem_reg(a, op, milstd_v_mem(a, ea, insn->rx, sz, RZ_ANALYSIS_ACC_W), insn->ra); + } else if (type == RZ_ANALYSIS_OP_TYPE_CMP) { + milstd_cmp_reg_mem(a, op, insn->ra, milstd_v_mem(a, ea, insn->rx, sz, RZ_ANALYSIS_ACC_R)); + } else { // Ra = Ra (op) [mem] + milstd_acc_mem(a, op, insn->ra, milstd_v_mem(a, ea, insn->rx, sz, RZ_ANALYSIS_ACC_R)); + } + break; + } + case MIL_FMT_IM_0_15: + case MIL_FMT_IM_1_16: { + ut64 ea = (ut64)insn->addr * 2; + if (type == RZ_ANALYSIS_OP_TYPE_LOAD) { // LM: memory into a register range + op->src[0] = milstd_v_mem(a, ea, insn->rx, sz, RZ_ANALYSIS_ACC_R); + } else if (type == RZ_ANALYSIS_OP_TYPE_STORE) { // STM/STC/STCI + milstd_mem_imm(op, milstd_v_mem(a, ea, insn->rx, sz, RZ_ANALYSIS_ACC_W), insn->imm8); + } else if (type == RZ_ANALYSIS_OP_TYPE_CMP) { // TB: test bit in memory + milstd_cmp_mem_imm(op, milstd_v_mem(a, ea, insn->rx, sz, RZ_ANALYSIS_ACC_R), insn->imm8); + } else { // SB/RB/INCM/DECM: read-modify-write the memory word + milstd_mem_imm(op, milstd_v_mem(a, ea, insn->rx, sz, RZ_ANALYSIS_ACC_R | RZ_ANALYSIS_ACC_W), insn->imm8); + } + break; + } + case MIL_FMT_B: + case MIL_FMT_BX: { + // Base-relative; the accumulator register is implied by the opcode and + // not modelled. Only the memory operand is recorded. + ut8 rx = (insn->format == MIL_FMT_BX) ? insn->rx : 0; + st64 disp = (insn->format == MIL_FMT_B) ? insn->imm8 : 0; + RzAnalysisValueAccess acc = (type == RZ_ANALYSIS_OP_TYPE_STORE) ? RZ_ANALYSIS_ACC_W : RZ_ANALYSIS_ACC_R; + RzAnalysisValue *mem = milstd_v_basemem(a, insn->br, rx, disp, sz, acc); + if (type == RZ_ANALYSIS_OP_TYPE_STORE) { + op->dst = mem; + } else { + op->src[0] = mem; + } + break; + } + default: + break; + } + + // op->access: flat list of every value touched, owning independent copies + // (op_fini frees src/dst and the list separately, so they must not alias). + RzList *acc = rz_list_newf((RzListFree)rz_analysis_value_free); + if (!acc) { + return; + } + if (op->dst) { + rz_list_append(acc, rz_analysis_value_copy(op->dst)); + } + for (size_t i = 0; i < RZ_ARRAY_SIZE(op->src); i++) { + if (op->src[i]) { + rz_list_append(acc, rz_analysis_value_copy(op->src[i])); + } + } + if (rz_list_empty(acc)) { + rz_list_free(acc); + } else { + op->access = acc; + } +} + +static void milstd_fill_operands(RzAnalysis *analysis, RzAnalysisOp *op, const MilStd1750Instruction *insn, RzAnalysisOpMask mask) { + milstd_set_stack(op, insn); + milstd_set_direction(op, insn->format); + milstd_set_val(op, insn); + milstd_set_ptr(op, insn); + milstd_set_datatype(op, insn); + milstd_set_reg(op, insn); + if (mask & RZ_ANALYSIS_OP_MASK_VAL) { + milstd_fill_val(analysis, op, insn); + } +} + static void set_invalid(RzAnalysisOp *op, ut64 addr) { op->family = RZ_ANALYSIS_OP_FAMILY_UNKNOWN; op->type = RZ_ANALYSIS_OP_TYPE_ILL; @@ -18,6 +623,9 @@ int rz_milstd1750_analysis_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, MilStd1750Instruction insn; if (!rz_milstd1750_decode(data, len, &insn)) { set_invalid(op, addr); + if (mask & RZ_ANALYSIS_OP_MASK_DISASM) { + op->mnemonic = rz_str_dup("invalid"); + } return -1; } @@ -26,340 +634,398 @@ int rz_milstd1750_analysis_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, op->family = RZ_ANALYSIS_OP_FAMILY_CPU; op->type = RZ_ANALYSIS_OP_TYPE_UNK; + if (mask & RZ_ANALYSIS_OP_MASK_DISASM) { + char *str = rz_milstd1750_stringify(&insn); + op->mnemonic = str ? str : rz_str_dup("invalid"); + } + // MIL-STD-1750A: encoded addresses are word indices; rizin uses // byte addresses with bits=8, so multiply by 2. ut64 icr_target = addr + (st64)(st8)insn.imm8 * 2; ut64 abs_target = (ut64)insn.addr * 2; ut64 next_pc = addr + insn.size; - // B-format opcodes encode the 2-bit BR field in the low bits of the - // opcode byte; mask off to get the canonical opcode for type lookup. - ut8 op8 = insn.raw_w1 >> 8; - if (insn.format == MIL_FMT_B) { - op8 &= 0xFC; - } - - // IM-format (0x4A): 4-bit opex selects which immediate op - if (insn.format == MIL_FMT_IM_OCX && op8 == 0x4A) { - switch (insn.opex) { - case 0x1: op->type = RZ_ANALYSIS_OP_TYPE_ADD; break; // AIM - case 0x2: op->type = RZ_ANALYSIS_OP_TYPE_SUB; break; // SIM - case 0x3: // MIM - case 0x4: op->type = RZ_ANALYSIS_OP_TYPE_MUL; break; // MSIM - case 0x5: // DIM - case 0x6: op->type = RZ_ANALYSIS_OP_TYPE_DIV; break; // DVIM - case 0x7: op->type = RZ_ANALYSIS_OP_TYPE_AND; break; // ANDM - case 0x8: op->type = RZ_ANALYSIS_OP_TYPE_OR; break; // ORIM - case 0x9: op->type = RZ_ANALYSIS_OP_TYPE_XOR; break; // XORM - case 0xA: op->type = RZ_ANALYSIS_OP_TYPE_CMP; break; // CIM - case 0xB: op->type = RZ_ANALYSIS_OP_TYPE_NOT; break; // NIM - } - return op->size; - } - - switch (op8) { + // insn.opcode is the canonical MIL_OP_* pattern the decoder matched: the + // instruction word with its operand bits cleared (the mask depends on the + // format, e.g. B hides a 2-bit BR field and BX/IM a 4-bit opcode extension + // inside the word). So it can be compared against the constants directly. + switch (insn.opcode) { // --- Special / control flow boundaries --- - case 0xFF: - if (insn.raw_w1 == 0xFFFF) { - op->type = RZ_ANALYSIS_OP_TYPE_TRAP; // BPT - op->eob = true; - } else { - op->type = RZ_ANALYSIS_OP_TYPE_NOP; - } + case MIL_OP_NOP: + op->type = RZ_ANALYSIS_OP_TYPE_NOP; break; - case 0x7F: // URS — Unstack IC and Return from Subroutine + case MIL_OP_BPT: + op->type = RZ_ANALYSIS_OP_TYPE_TRAP; + op->eob = true; + break; + case MIL_OP_URS: // URS — Unstack IC and Return from Subroutine op->type = RZ_ANALYSIS_OP_TYPE_RET; op->eob = true; break; // --- ICR branches: target = addr + disp*2 (D = signed 8-bit) --- - case 0x74: // BR — unconditional + case MIL_OP_BR: // BR — unconditional + op->cond = RZ_TYPE_COND_AL; op->type = RZ_ANALYSIS_OP_TYPE_JMP; op->jump = icr_target; op->eob = true; break; - case 0x75: // BEZ - case 0x76: // BLT - case 0x78: // BLE - case 0x79: // BGT - case 0x7A: // BNZ - case 0x7B: // BGE + case MIL_OP_BEZ: // BEZ — branch if equal zero (Z) + case MIL_OP_BLT: // BLT — branch if less than zero (N) + case MIL_OP_BLE: // BLE — branch if less or equal zero (N|Z) + case MIL_OP_BGT: // BGT — branch if greater than zero (P) + case MIL_OP_BNZ: // BNZ — branch if not zero (P|N) + case MIL_OP_BGE: // BGE — branch if greater or equal zero (P|Z) op->type = RZ_ANALYSIS_OP_TYPE_CJMP; + switch (insn.opcode) { + case MIL_OP_BEZ: op->cond = RZ_TYPE_COND_EQ; break; + case MIL_OP_BLT: op->cond = RZ_TYPE_COND_LT; break; + case MIL_OP_BLE: op->cond = RZ_TYPE_COND_LE; break; + case MIL_OP_BGT: op->cond = RZ_TYPE_COND_GT; break; + case MIL_OP_BNZ: op->cond = RZ_TYPE_COND_NE; break; + case MIL_OP_BGE: op->cond = RZ_TYPE_COND_GE; break; + } op->jump = icr_target; op->fail = next_pc; break; // --- Memory-format jumps: target word in w2 → byte = w2*2 --- - case 0x70: // JC C, LABEL — Jump on Condition (direct) + case MIL_OP_JC: // JC C, LABEL — Jump on Condition (direct) if (insn.cond == 0) { op->type = RZ_ANALYSIS_OP_TYPE_NOP; } else if (insn.cond == 0x7 || insn.cond == 0xF) { + op->cond = RZ_TYPE_COND_AL; op->type = RZ_ANALYSIS_OP_TYPE_JMP; op->jump = abs_target; op->eob = true; } else { + op->cond = jc_cond_to_type(insn.cond); op->type = RZ_ANALYSIS_OP_TYPE_CJMP; op->jump = abs_target; op->fail = next_pc; } break; - case 0x71: // JCI C, ADDR — Jump on Condition (indirect) + case MIL_OP_JCI: // JCI C, ADDR — Jump on Condition (indirect) if (insn.cond == 0) { op->type = RZ_ANALYSIS_OP_TYPE_NOP; } else if (insn.cond == 0x7 || insn.cond == 0xF) { - op->type = RZ_ANALYSIS_OP_TYPE_MJMP; // unconditional indirect + op->cond = RZ_TYPE_COND_AL; + op->type = RZ_ANALYSIS_OP_TYPE_MJMP; op->eob = true; } else { + op->cond = jc_cond_to_type(insn.cond); op->type = RZ_ANALYSIS_OP_TYPE_MCJMP; op->fail = next_pc; } break; - case 0x72: // JS — Jump to Subroutine (return addr in RA) - case 0x7E: // SJS — Stack IC and Jump to Subroutine + case MIL_OP_JS: // JS — Jump to Subroutine (return addr in RA) + case MIL_OP_SJS: // SJS — Stack IC and Jump to Subroutine op->type = RZ_ANALYSIS_OP_TYPE_CALL; op->jump = abs_target; op->fail = next_pc; break; - case 0x73: // SOJ — Subtract One and Jump (cond on RA != 0) + case MIL_OP_SOJ: // SOJ — Subtract One and Jump (taken while RA != 0) op->type = RZ_ANALYSIS_OP_TYPE_CJMP; + op->cond = RZ_TYPE_COND_NE; op->jump = abs_target; op->fail = next_pc; break; - case 0x77: // BEX N — Branch to Executive (interrupt-vectored) + case MIL_OP_BEX: // BEX N — Branch to Executive (interrupt-vectored) op->type = RZ_ANALYSIS_OP_TYPE_UCALL; op->eob = true; break; - case 0x4F: // BIF — Branch on Input Flag (target unknown statically) + case MIL_OP_BIF: // BIF — Branch on Input Flag (target unknown statically) op->type = RZ_ANALYSIS_OP_TYPE_CJMP; op->fail = next_pc; break; // --- LST/LSTI: load (MK,SW,IC) from memory; unconditional indirect jump --- - case 0x7C: // LSTI ADDR — indirect load status (also reloads IC) - case 0x7D: // LST ADDR — direct load status (also reloads IC) + case MIL_OP_LSTI: // LSTI ADDR — indirect load status (also reloads IC) + case MIL_OP_LST: // LST ADDR — direct load status (also reloads IC) op->type = RZ_ANALYSIS_OP_TYPE_MJMP; op->family = RZ_ANALYSIS_OP_FAMILY_PRIV; op->eob = true; break; // --- I/O --- - case 0x48: // XIO - case 0x49: // VIO + case MIL_OP_XIO: + case MIL_OP_VIO: op->type = RZ_ANALYSIS_OP_TYPE_IO; op->family = RZ_ANALYSIS_OP_FAMILY_IO; break; // --- Stack --- - case 0x8F: op->type = RZ_ANALYSIS_OP_TYPE_POP; break; // POPM - case 0x9F: + case MIL_OP_POPM: op->type = RZ_ANALYSIS_OP_TYPE_POP; break; // POPM + case MIL_OP_PSHM: op->type = RZ_ANALYSIS_OP_TYPE_PUSH; - break; // PSHM + break; // --- Move / exchange --- - case 0x93: // MOV - case 0xEC: // XBR - case 0xED: // XWR + case MIL_OP_MOV: + case MIL_OP_XBR: + case MIL_OP_XWR: op->type = RZ_ANALYSIS_OP_TYPE_MOV; break; // --- Add --- - case 0x10: // AB - case 0xA0: // A - case 0xA1: // AR - case 0xA2: // AISP - case 0xA3: // INCM - case 0xA4: // ABS - case 0xA6: // DA - case 0xA7: // DAR - case 0xA8: // FA - case 0xA9: // FAR - case 0xAA: // EFA - case 0xAB: // EFAR - case 0xAC: // FABS - case 0xAD: // UAR - case 0xAE: // UA + case MIL_OP_FA: + case MIL_OP_FAB: + case MIL_OP_FABX: + case MIL_OP_FAR: + case MIL_OP_EFA: + case MIL_OP_EFAR: + case MIL_OP_FABS: + case MIL_OP_UAR: + case MIL_OP_UA: + op->type = RZ_ANALYSIS_OP_TYPE_ADD; + break; + case MIL_OP_AB: + case MIL_OP_ABX: + case MIL_OP_A: + case MIL_OP_AR: + case MIL_OP_AIM: + case MIL_OP_AISP: + case MIL_OP_INCM: + case MIL_OP_ABS: + case MIL_OP_DABS: + case MIL_OP_DA: + case MIL_OP_DAR: op->type = RZ_ANALYSIS_OP_TYPE_ADD; + op->sign = true; break; // --- Sub --- - case 0x14: // SBB - case 0xB0: // S - case 0xB1: // SR - case 0xB2: // SISP - case 0xB3: // DECM - case 0xB4: // NEG - case 0xB5: // DNEG - case 0xB6: // DS - case 0xB7: // DSR - case 0xB8: // FS - case 0xB9: // FSR - case 0xBA: // EFS - case 0xBB: // EFSR - case 0xBC: // FNEG - case 0xBD: // USR - case 0xBE: // US + case MIL_OP_FS: + case MIL_OP_FSB: + case MIL_OP_FSBX: + case MIL_OP_FSR: + case MIL_OP_EFS: + case MIL_OP_EFSR: + case MIL_OP_FNEG: + case MIL_OP_USR: + case MIL_OP_US: op->type = RZ_ANALYSIS_OP_TYPE_SUB; break; + case MIL_OP_SBB: + case MIL_OP_SBBX: + case MIL_OP_S: + case MIL_OP_SR: + case MIL_OP_SIM: + case MIL_OP_SISP: + case MIL_OP_DECM: + case MIL_OP_NEG: + case MIL_OP_DNEG: + case MIL_OP_DS: + case MIL_OP_DSR: + op->type = RZ_ANALYSIS_OP_TYPE_SUB; + op->sign = true; + break; // --- Mul --- - case 0x18: // MB - case 0xC0: // MS - case 0xC1: // MSR - case 0xC2: // MISP - case 0xC3: // MISN - case 0xC4: // M - case 0xC5: // MR - case 0xC6: // DM - case 0xC7: // DMR - case 0xC8: // FM - case 0xC9: // FMR - case 0xCA: // EFM - case 0xCB: // EFMR + case MIL_OP_FM: + case MIL_OP_FMB: + case MIL_OP_FMBX: + case MIL_OP_FMR: + case MIL_OP_EFM: + case MIL_OP_EFMR: + op->type = RZ_ANALYSIS_OP_TYPE_MUL; + break; + case MIL_OP_MB: + case MIL_OP_MBX: + case MIL_OP_MS: + case MIL_OP_MSR: + case MIL_OP_MIM: + case MIL_OP_MSIM: + case MIL_OP_MISP: + case MIL_OP_MISN: + case MIL_OP_M: + case MIL_OP_MR: + case MIL_OP_DM: + case MIL_OP_DMR: op->type = RZ_ANALYSIS_OP_TYPE_MUL; + op->sign = true; break; // --- Div --- - case 0x1C: // DB - case 0xD0: // DV - case 0xD1: // DVR - case 0xD2: // DISP - case 0xD3: // DISN - case 0xD4: // D - case 0xD5: // DR - case 0xD6: // DD - case 0xD7: // DDR - case 0xD8: // FD - case 0xD9: // FDR - case 0xDA: // EFD - case 0xDB: // EFDR + case MIL_OP_FD: + case MIL_OP_FDB: + case MIL_OP_FDBX: + case MIL_OP_FDR: + case MIL_OP_EFD: + case MIL_OP_EFDR: + op->type = RZ_ANALYSIS_OP_TYPE_DIV; + break; + case MIL_OP_DB: + case MIL_OP_DBX: + case MIL_OP_DV: + case MIL_OP_DVR: + case MIL_OP_DIM: + case MIL_OP_DVIM: + case MIL_OP_DISP: + case MIL_OP_DISN: + case MIL_OP_D: + case MIL_OP_DR: + case MIL_OP_DD: + case MIL_OP_DDR: op->type = RZ_ANALYSIS_OP_TYPE_DIV; + op->sign = true; break; // --- Logical --- - case 0x34: // ANDB - case 0xE2: // AND - case 0xE3: // ANDR + case MIL_OP_ANDB: + case MIL_OP_ANDX: + case MIL_OP_AND: + case MIL_OP_ANDM: + case MIL_OP_ANDR: op->type = RZ_ANALYSIS_OP_TYPE_AND; break; - case 0x30: // ORB - case 0xE0: // OR - case 0xE1: // ORR + case MIL_OP_ORB: + case MIL_OP_ORBX: + case MIL_OP_OR: + case MIL_OP_ORIM: + case MIL_OP_ORR: op->type = RZ_ANALYSIS_OP_TYPE_OR; break; - case 0xE4: // XOR - case 0xE5: // XORR + case MIL_OP_XOR: + case MIL_OP_XORM: + case MIL_OP_XORR: op->type = RZ_ANALYSIS_OP_TYPE_XOR; break; - case 0xE6: // N - case 0xE7: // NR + case MIL_OP_N: + case MIL_OP_NIM: + case MIL_OP_NR: op->type = RZ_ANALYSIS_OP_TYPE_NOT; break; + // --- Float/integer conversion --- + case MIL_OP_FIX: + case MIL_OP_FLT: + case MIL_OP_EFIX: + case MIL_OP_EFLT: + op->type = RZ_ANALYSIS_OP_TYPE_CAST; + break; + // --- Shifts --- - case 0x60: // SLL - case 0x63: // SLC - case 0x65: // DSLL - case 0x68: // DSLC - case 0x6A: // SLR - case 0x6D: // DSLR + case MIL_OP_SLL: + case MIL_OP_SLC: + case MIL_OP_DSLL: + case MIL_OP_DSLC: + case MIL_OP_SLR: + case MIL_OP_DSLR: op->type = RZ_ANALYSIS_OP_TYPE_SHL; break; - case 0x61: // SRL - case 0x62: // SRA - case 0x66: // DSRL - case 0x67: // DSRA - case 0x6B: // SAR - case 0x6C: // SCR - case 0x6E: // DSAR - case 0x6F: // DSCR + case MIL_OP_SRL: + case MIL_OP_DSRL: + case MIL_OP_SCR: + case MIL_OP_DSCR: + op->type = RZ_ANALYSIS_OP_TYPE_SHR; + break; + case MIL_OP_SRA: + case MIL_OP_DSRA: + case MIL_OP_SAR: + case MIL_OP_DSAR: op->type = RZ_ANALYSIS_OP_TYPE_SHR; + op->sign = true; break; // --- Compare --- - case 0x38: // CB - case 0xF0: // C - case 0xF1: // CR - case 0xF2: // CISP - case 0xF3: // CISN - case 0xF4: // CBL - case 0xF6: // DC - case 0xF7: // DCR - case 0xF8: // FC - case 0xF9: // FCR - case 0xFA: // EFC - case 0xFB: // EFCR - case 0xFC: // UCR - case 0xFD: // UC + case MIL_OP_FC: + case MIL_OP_FCB: + case MIL_OP_FCBX: + case MIL_OP_FCR: + case MIL_OP_EFC: + case MIL_OP_EFCR: + case MIL_OP_UCR: + case MIL_OP_UC: + case MIL_OP_UCIM: // unsigned compare, immediate + op->type = RZ_ANALYSIS_OP_TYPE_CMP; + break; + case MIL_OP_CB: + case MIL_OP_CBX: + case MIL_OP_C: + case MIL_OP_CR: + case MIL_OP_CIM: + case MIL_OP_CISP: + case MIL_OP_CISN: + case MIL_OP_CBL: + case MIL_OP_DC: + case MIL_OP_DCR: op->type = RZ_ANALYSIS_OP_TYPE_CMP; + op->sign = true; break; // --- Loads --- - case 0x00: // LB - case 0x04: // DLB - case 0x80: // L - case 0x81: // LR - case 0x82: // LISP - case 0x83: // LISN - case 0x84: // LI - case 0x85: // LIM - case 0x86: // DL - case 0x87: // DLR - case 0x88: // DLI - case 0x89: // LM - case 0x8A: // EFL - case 0x8B: // LUB - case 0x8C: // LLB - case 0x8D: // LUBI - case 0x8E: // LLBI - case 0xDE: // LE - case 0xDF: // DLE + case MIL_OP_LB: + case MIL_OP_LBX: + case MIL_OP_DLB: + case MIL_OP_DLBX: + case MIL_OP_L: + case MIL_OP_LR: + case MIL_OP_LISP: + case MIL_OP_LISN: + case MIL_OP_LI: + case MIL_OP_LIM: + case MIL_OP_DL: + case MIL_OP_DLR: + case MIL_OP_DLI: + case MIL_OP_LM: + case MIL_OP_EFL: + case MIL_OP_LUB: + case MIL_OP_LLB: + case MIL_OP_LUBI: + case MIL_OP_LLBI: + case MIL_OP_LE: + case MIL_OP_DLE: op->type = RZ_ANALYSIS_OP_TYPE_LOAD; break; // --- Stores --- - case 0x08: // STB - case 0x0C: // DSTB - case 0x90: // ST - case 0x91: // STC - case 0x92: // STCI - case 0x94: // STI - case 0x95: // SFBS - case 0x96: // DST - case 0x97: // SRM - case 0x98: // DSTI - case 0x99: // STM - case 0x9A: // EFST - case 0x9B: // STUB - case 0x9C: // STLB - case 0x9D: // SUBI - case 0x9E: // SLBI - case 0xDC: // STE - case 0xDD: // DSTE + case MIL_OP_STB: + case MIL_OP_STBX: + case MIL_OP_DSTB: + case MIL_OP_DSTX: + case MIL_OP_ST: + case MIL_OP_STC: + case MIL_OP_STCI: + case MIL_OP_STI: + case MIL_OP_SFBS: + case MIL_OP_DST: + case MIL_OP_SRM: + case MIL_OP_DSTI: + case MIL_OP_STM: + case MIL_OP_EFST: + case MIL_OP_STUB: + case MIL_OP_STLB: + case MIL_OP_SUBI: + case MIL_OP_SLBI: + case MIL_OP_STE: + case MIL_OP_DSTE: op->type = RZ_ANALYSIS_OP_TYPE_STORE; break; // --- Bit set/reset/test --- - case 0x50: // SB - case 0x51: // SBR - case 0x52: // SBI - case 0x59: // TSB - case 0x5A: // SVBR + case MIL_OP_SB: + case MIL_OP_SBR: + case MIL_OP_SBI: + case MIL_OP_TSB: + case MIL_OP_SVBR: op->type = RZ_ANALYSIS_OP_TYPE_OR; break; - case 0x53: // RB - case 0x54: // RBR - case 0x55: // RBI - case 0x5C: // RVBR + case MIL_OP_RB: + case MIL_OP_RBR: + case MIL_OP_RBI: + case MIL_OP_RVBR: op->type = RZ_ANALYSIS_OP_TYPE_AND; break; - case 0x56: // TB - case 0x57: // TBR - case 0x58: // TBI - case 0x5E: // TVBR + case MIL_OP_TB: + case MIL_OP_TBR: + case MIL_OP_TBI: + case MIL_OP_TVBR: op->type = RZ_ANALYSIS_OP_TYPE_CMP; break; } + milstd_fill_operands(analysis, op, &insn, mask); return op->size; } diff --git a/test/db/analysis/milstd1750 b/test/db/analysis/milstd1750 index fedc1b66248..5ff138c84f5 100644 --- a/test/db/analysis/milstd1750 +++ b/test/db/analysis/milstd1750 @@ -42,76 +42,122 @@ wx FF00 A112 A0301234 7410 FFFF pi 5 s 0x100 wx 7410 -ao~type,size,jump +ao~^type,size,jump s 0x100 wx 74F8 -ao~type,size,jump +ao~^type,size,jump s 0x100 wx 7505 7610 7820 7930 7A40 7B50 -ao 6~type,size,jump,fail +ao 6~^type,size,jump,fail s 0x100 wx 705F0800 -ao~type,size,jump,fail +ao~^type,size,jump,fail s 0x100 wx 72002000 -ao~type,size,jump +ao~^type,size,jump s 0x100 wx 7E000800 -ao~type,size,jump +ao~^type,size,jump s 0x100 wx 73001500 -ao~type,size,jump,fail +ao~^type,size,jump,fail s 0x100 wx 7F00 -ao~type,size +ao~^type,size s 0x100 wx FFFF FF00 -ao 2~type,size +ao 2~^type,size s 0x100 wx A112 B112 C512 D112 -ao 4~type,size +ao 4~^type,size s 0x100 wx E312 E134 E556 E712 -ao 4~type,size +ao 4~^type,size s 0x100 wx 6043 6121 6232 -ao 3~type,size +ao 3~^type,size s 0x100 wx 80501234 90301234 0005 0805 -ao 4~type,size +ao 4~^type,size s 0x100 wx 8F35 9F35 -ao 2~type,size +ao 2~^type,size s 0x100 wx 48302000 49101234 -ao 2~type,size +ao 2~^type,size s 0x100 wx 9312 -ao~type,size +ao~^type,size s 0x100 wx F0501234 F912 -ao 2~type,size +ao 2~^type,size s 0x100 wx 4A00 -ao~type,size +ao~^type,size s 0x100 wx 70000800 70700800 70500800 -ao 3~type,size,jump,fail +ao 3~^type,size,jump,fail s 0x100 wx 71000800 71F00800 71200800 -ao 3~type,size,fail +ao 3~^type,size,fail s 0x100 wx 7D001234 7C001234 -ao 2~type,size,family +ao 2~^type,size,family s 0x100 wx 7705 -ao~type,size +ao~^type,size s 0x100 wx 72002000 7E002000 -ao 2~type,size,jump,fail +ao 2~^type,size,jump,fail s 0x100 wx 48302000 49101234 ao 2~family +s 0x100;wx A112;ao~reg +s 0x100;wx A0231234;ao~reg +s 0x100;wx A0201234;ao~datatype +s 0x100;wx A6201234;ao~datatype +s 0x100;wx A8201234;ao~datatype +s 0x100;wx AA201234;ao~datatype +s 0x100;wx A234;ao~val +s 0x100;wx 6043;ao~val +s 0x100;wx 4A011234;ao~val +s 0x100;wx 80201234;ao~direction +s 0x100;wx 90201234;ao~direction +s 0x100;wx 9F36;ao~direction +s 0x100;wx 8F36;ao~direction +s 0x100;wx 72002000;ao~direction +s 0x100;wx 80200010 7F00;af +s 0x200;wx 90400018 7F00;af +s 0x300;wx 72000028 7F00;af +axt @ 0x20 +axt @ 0x30 +axt @ 0x50 +s 0x100;wx 48302000;ao~^type,family +s 0x100;wx 49101234;ao~^type,family +s 0x100;wx 7D001234;ao~^type,family +s 0x100;wx 7C001234;ao~^type,family +s 0x100;wx 9F36;ao~^type,stackop,stackptr +s 0x100;wx 8F36;ao~^type,stackop,stackptr +s 0x100;wx 7E002000;ao~^type,stackop,stackptr +s 0x100;wx 7F00;ao~^type,stackop,stackptr +s 0x100;wx 9F52;ao~^type,stackop,stackptr +s 0x100;wx F0201234;ao~^type,sign +s 0x100;wx FD201234;ao~^type,sign +s 0x100;wx F8201234;ao~^type,sign +s 0x100;wx 6230;ao~^type,sign +s 0x100;wx 6130;ao~^type,sign +s 0x100;wx 70100800;ao~^type,cond +s 0x100;wx 70800800;ao~^type,cond +s 0x100;wx 70900800;ao~^type,cond +s 0x100;wx 70700800;ao~^type,cond +s 0x100;wx 71200800;ao~^type,cond +s 0x100;wx 7501;ao~^type,cond +s 0x100;wx 7610;ao~^type,cond +s 0x100;wx 7820;ao~^type,cond +s 0x100;wx 7930;ao~^type,cond +s 0x100;wx 7A40;ao~^type,cond +s 0x100;wx 7B50;ao~^type,cond +s 0x100;wx 73001500;ao~^type,cond EOF EXPECT=<