#include "config.h" #include #ifdef HAVE_UNISTD_H #include #endif #include "mn10300_sim.h" #include "simops.h" #include "sys/syscall.h" #include "bfd.h" #include #include #include #include #define REG0(X) ((X) & 0x3) #define REG1(X) (((X) & 0xc) >> 2) #define REG0_4(X) (((X) & 0x30) >> 4) #define REG0_8(X) (((X) & 0x300) >> 8) #define REG1_8(X) (((X) & 0xc00) >> 10) #define REG0_16(X) (((X) & 0x30000) >> 16) #define REG1_16(X) (((X) & 0xc0000) >> 18) /* mov imm8, dn */ void OP_8000 (insn, extension) unsigned long insn, extension; { State.regs[REG_D0 + REG0_8 (insn)] = SEXT8 (insn & 0xff); } /* mov dm, dn */ void OP_80 (insn, extension) unsigned long insn, extension; { State.regs[REG_D0 + REG0 (insn)] = State.regs[REG_D0 + REG1 (insn)]; } /* mov dm, an */ void OP_F1E0 (insn, extension) unsigned long insn, extension; { State.regs[REG_A0 + REG0 (insn)] = State.regs[REG_D0 + REG1 (insn)]; } /* mov am, dn */ void OP_F1D0 (insn, extension) unsigned long insn, extension; { State.regs[REG_D0 + REG0 (insn)] = State.regs[REG_A0 + REG1 (insn)]; } /* mov imm8, an */ void OP_9000 (insn, extension) unsigned long insn, extension; { State.regs[REG_A0 + REG0_8 (insn)] = insn & 0xff; } /* mov am, an */ void OP_90 (insn, extension) unsigned long insn, extension; { State.regs[REG_A0 + REG0 (insn)] = State.regs[REG_A0 + REG1 (insn)]; } /* mov sp, an */ void OP_3C (insn, extension) unsigned long insn, extension; { State.regs[REG_A0 + REG0 (insn)] = State.regs[REG_SP]; } /* mov am, sp */ void OP_F2F0 (insn, extension) unsigned long insn, extension; { State.regs[REG_SP] = State.regs[REG_A0 + REG1 (insn)]; } /* mov psw, dn */ void OP_F2E4 (insn, extension) unsigned long insn, extension; { State.regs[REG_D0 + REG0 (insn)] = PSW; } /* mov dm, psw */ void OP_F2F3 (insn, extension) unsigned long insn, extension; { PSW = State.regs[REG_D0 + REG1 (insn)]; } /* mov mdr, dn */ void OP_F2E0 (insn, extension) unsigned long insn, extension; { State.regs[REG_D0 + REG0 (insn)] = State.regs[REG_MDR]; } /* mov dm, mdr */ void OP_F2F2 (insn, extension) unsigned long insn, extension; { State.regs[REG_MDR] = State.regs[REG_D0 + REG1 (insn)]; } /* mov (am), dn */ void OP_70 (insn, extension) unsigned long insn, extension; { State.regs[REG_D0 + REG1 (insn)] = load_mem (State.regs[REG_A0 + REG0 (insn)], 4); } /* mov (d8,am), dn */ void OP_F80000 (insn, extension) unsigned long insn, extension; { State.regs[REG_D0 + REG1_8 (insn)] = load_mem ((State.regs[REG_A0 + REG0_8 (insn)] + SEXT8 (insn & 0xff)), 4); } /* mov (d16,am), dn */ void OP_FA000000 (insn, extension) unsigned long insn, extension; { State.regs[REG_D0 + REG1_16 (insn)] = load_mem ((State.regs[REG_A0 + REG0_16 (insn)] + SEXT16 (insn & 0xffff)), 4); } /* mov (d32,am), dn */ void OP_FC000000 (insn, extension) unsigned long insn, extension; { State.regs[REG_D0 + REG1_16 (insn)] = load_mem ((State.regs[REG_A0 + REG0_16 (insn)] + ((insn & 0xffff) << 16) + extension), 4); } /* mov (d8,sp), dn */ void OP_5800 (insn, extension) unsigned long insn, extension; { State.regs[REG_D0 + REG0_8 (insn)] = load_mem (State.regs[REG_SP] + (insn & 0xff), 4); } /* mov (d16,sp), dn */ void OP_FAB40000 (insn, extension) unsigned long insn, extension; { State.regs[REG_D0 + REG0_16 (insn)] = load_mem (State.regs[REG_SP] + (insn & 0xffff), 4); } /* mov (d32,sp), dn */ void OP_FCB40000 (insn, extension) unsigned long insn, extension; { State.regs[REG_D0 + REG0_16 (insn)] = load_mem (State.regs[REG_SP] + (((insn & 0xffff) << 16) + extension), 4); } /* mov (di,am), dn */ void OP_F300 (insn, extension) unsigned long insn, extension; { State.regs[REG_D0 + REG0_4 (insn)] = load_mem ((State.regs[REG_A0 + REG0 (insn)] + State.regs[REG_D0 + REG1 (insn)]), 4); } /* mov (abs16), dn */ void OP_300000 (insn, extension) unsigned long insn, extension; { State.regs[REG_D0 + REG0_16 (insn)] = load_mem ((insn & 0xffff), 4); } /* mov (abs32), dn */ void OP_FCA40000 (insn, extension) unsigned long insn, extension; { State.regs[REG_D0 + REG0_16 (insn)] = load_mem ((((insn & 0xffff) << 16) + extension), 4); } /* mov (am), an */ void OP_F000 (insn, extension) unsigned long insn, extension; { State.regs[REG_A0 + REG1 (insn)] = load_mem (State.regs[REG_A0 + REG0 (insn)], 4); } /* mov (d8,am), an */ void OP_F82000 (insn, extension) unsigned long insn, extension; { State.regs[REG_A0 + REG1_8 (insn)] = load_mem ((State.regs[REG_A0 + REG0_8 (insn)] + SEXT8 (insn & 0xff)), 4); } /* mov (d16,am), an */ void OP_FA200000 (insn, extension) unsigned long insn, extension; { State.regs[REG_A0 + REG1_16 (insn)] = load_mem ((State.regs[REG_A0 + REG0_16 (insn)] + SEXT16 (insn & 0xffff)), 4); } /* mov (d32,am), an */ void OP_FC200000 (insn, extension) unsigned long insn, extension; { State.regs[REG_A0 + REG1_16 (insn)] = load_mem ((State.regs[REG_A0 + REG0_16 (insn)] + ((insn & 0xffff) << 16) + extension), 4); } /* mov (d8,sp), an */ void OP_5C00 (insn, extension) unsigned long insn, extension; { State.regs[REG_A0 + REG0_8 (insn)] = load_mem (State.regs[REG_SP] + (insn & 0xff), 4); } /* mov (d16,sp), an */ void OP_FAB00000 (insn, extension) unsigned long insn, extension; { State.regs[REG_A0 + REG0_16 (insn)] = load_mem (State.regs[REG_SP] + (insn & 0xffff), 4); } /* mov (d32,sp), an */ void OP_FCB00000 (insn, extension) unsigned long insn, extension; { State.regs[REG_A0 + REG0_16 (insn)] = load_mem (State.regs[REG_SP] + (((insn & 0xffff) << 16) + extension), 4); } /* mov (di,am), an */ void OP_F380 (insn, extension) unsigned long insn, extension; { State.regs[REG_A0 + REG0_4 (insn)] = load_mem ((State.regs[REG_A0 + REG0 (insn)] + State.regs[REG_D0 + REG1 (insn)]), 4); } /* mov (abs16), an */ void OP_FAA00000 (insn, extension) unsigned long insn, extension; { State.regs[REG_A0 + REG0_16 (insn)] = load_mem ((insn & 0xffff), 4); } /* mov (abs32), an */ void OP_FCA00000 (insn, extension) unsigned long insn, extension; { State.regs[REG_A0 + REG0_16 (insn)] = load_mem ((((insn & 0xffff) << 16) + extension), 4); } /* mov (d8,am), sp */ void OP_F8F000 (insn, extension) unsigned long insn, extension; { State.regs[REG_SP] = load_mem ((State.regs[REG_A0 + REG0_8 (insn)] + SEXT8 (insn & 0xff)), 4); } /* mov dm, (an) */ void OP_60 (insn, extension) unsigned long insn, extension; { store_mem (State.regs[REG_A0 + REG0 (insn)], 4, State.regs[REG_D0 + REG1 (insn)]); } /* mov dm, (d8,an) */ void OP_F81000 (insn, extension) unsigned long insn, extension; { store_mem ((State.regs[REG_A0 + REG0_8 (insn)] + SEXT8 (insn & 0xff)), 4, State.regs[REG_D0 + REG1_8 (insn)]); } /* mov dm (d16,an) */ void OP_FA100000 (insn, extension) unsigned long insn, extension; { store_mem ((State.regs[REG_A0 + REG0_16 (insn)] + SEXT16 (insn & 0xffff)), 4, State.regs[REG_D0 + REG1_16 (insn)]); } /* mov dm (d32,an) */ void OP_FC100000 (insn, extension) unsigned long insn, extension; { store_mem ((State.regs[REG_A0 + REG0_16 (insn)] + ((insn & 0xffff) << 16) + extension), 4, State.regs[REG_D0 + REG1_16 (insn)]); } /* mov dm, (d8,sp) */ void OP_4200 (insn, extension) unsigned long insn, extension; { store_mem (State.regs[REG_SP] + (insn & 0xff), 4, State.regs[REG_D0 + REG1_8 (insn)]); } /* mov dm, (d16,sp) */ void OP_FA910000 (insn, extension) unsigned long insn, extension; { store_mem (State.regs[REG_SP] + (insn & 0xffff), 4, State.regs[REG_D0 + REG1_16 (insn)]); } /* mov dm, (d32,sp) */ void OP_FC910000 (insn, extension) unsigned long insn, extension; { store_mem (State.regs[REG_SP] + (((insn & 0xffff) << 16) + extension), 4, State.regs[REG_D0 + REG1_16 (insn)]); } /* mov dm, (di,an) */ void OP_F340 (insn, extension) unsigned long insn, extension; { store_mem ((State.regs[REG_A0 + REG0 (insn)] + State.regs[REG_D0 + REG1 (insn)]), 4, State.regs[REG_D0 + REG0_4 (insn)]); } /* mov dm, (abs16) */ void OP_10000 (insn, extension) unsigned long insn, extension; { store_mem ((insn & 0xffff), 4, State.regs[REG_D0 + REG1_16 (insn)]); } /* mov dm, (abs32) */ void OP_FC810000 (insn, extension) unsigned long insn, extension; { store_mem ((((insn & 0xffff) << 16) + extension), 4, State.regs[REG_D0 + REG1_16 (insn)]); } /* mov am, (an) */ void OP_F010 (insn, extension) unsigned long insn, extension; { store_mem (State.regs[REG_A0 + REG0 (insn)], 4, State.regs[REG_A0 + REG1 (insn)]); } /* mov am, (d8,an) */ void OP_F83000 (insn, extension) unsigned long insn, extension; { store_mem ((State.regs[REG_A0 + REG0_8 (insn)] + SEXT8 (insn & 0xff)), 4, State.regs[REG_A0 + REG1_8 (insn)]); } /* mov am, (d16,an) */ void OP_FA300000 (insn, extension) unsigned long insn, extension; { store_mem ((State.regs[REG_A0 + REG0_16 (insn)] + SEXT16 (insn & 0xffff)), 4, State.regs[REG_A0 + REG1_16 (insn)]); } /* mov am, (d32,an) */ void OP_FC300000 (insn, extension) unsigned long insn, extension; { store_mem ((State.regs[REG_A0 + REG0_16 (insn)] + ((insn & 0xffff) << 16) + extension), 4, State.regs[REG_A0 + REG1_16 (insn)]); } /* mov am, (d8,sp) */ void OP_4300 (insn, extension) unsigned long insn, extension; { store_mem (State.regs[REG_SP] + (insn & 0xff), 4, State.regs[REG_A0 + REG1_8 (insn)]); } /* mov am, (d16,sp) */ void OP_FA900000 (insn, extension) unsigned long insn, extension; { store_mem (State.regs[REG_SP] + (insn & 0xffff), 4, State.regs[REG_A0 + REG1_16 (insn)]); } /* mov am, (d32,sp) */ void OP_FC900000 (insn, extension) unsigned long insn, extension; { store_mem (State.regs[REG_SP] + (((insn & 0xffff) << 16) + extension), 4, State.regs[REG_A0 + REG1_16 (insn)]); } /* mov am, (di,an) */ void OP_F3C0 (insn, extension) unsigned long insn, extension; { store_mem ((State.regs[REG_A0 + REG0 (insn)] + State.regs[REG_D0 + REG1 (insn)]), 4, State.regs[REG_A0 + REG0_4 (insn)]); } /* mov am, (abs16) */ void OP_FA800000 (insn, extension) unsigned long insn, extension; { store_mem ((insn & 0xffff), 4, State.regs[REG_A0 + REG1_16 (insn)]); } /* mov am, (abs32) */ void OP_FC800000 (insn, extension) unsigned long insn, extension; { store_mem ((((insn & 0xffff) << 16) + extension), 4, State.regs[REG_A0 + REG1_16 (insn)]); } /* mov sp, (d8,an) */ void OP_F8F400 (insn, extension) unsigned long insn, extension; { store_mem (State.regs[REG_A0 + REG0_8 (insn)] + SEXT8 (insn & 0xff), 4, State.regs[REG_SP]); } /* mov imm16, dn */ void OP_2C0000 (insn, extension) unsigned long insn, extension; { unsigned long value; value = SEXT16 (insn & 0xffff); State.regs[REG_D0 + REG0_16 (insn)] = value; } /* mov imm32,dn */ void OP_FCCC0000 (insn, extension) unsigned long insn, extension; { unsigned long value; value = ((insn & 0xffff) << 16) + extension; State.regs[REG_D0 + REG0_16 (insn)] = value; } /* mov imm16, an */ void OP_240000 (insn, extension) unsigned long insn, extension; { unsigned long value; value = insn & 0xffff; State.regs[REG_A0 + REG0_16 (insn)] = value; } /* mov imm32, an */ void OP_FCDC0000 (insn, extension) unsigned long insn, extension; { unsigned long value; value = ((insn & 0xffff) << 16) + extension; State.regs[REG_A0 + REG0_16 (insn)] = value; } /* movbu (am), dn */ void OP_F040 (insn, extension) unsigned long insn, extension; { State.regs[REG_D0 + REG1 (insn)] = load_mem (State.regs[REG_A0 + REG0 (insn)], 1); } /* movbu (d8,am), dn */ void OP_F84000 (insn, extension) unsigned long insn, extension; { State.regs[REG_D0 + REG1_8 (insn)] = load_mem ((State.regs[REG_A0 + REG0_8 (insn)] + SEXT8 (insn & 0xff)), 1); } /* movbu (d16,am), dn */ void OP_FA400000 (insn, extension) unsigned long insn, extension; { State.regs[REG_D0 + REG1_16 (insn)] = load_mem ((State.regs[REG_A0 + REG0_16 (insn)] + SEXT16 (insn & 0xffff)), 1); } /* movbu (d32,am), dn */ void OP_FC400000 (insn, extension) unsigned long insn, extension; { State.regs[REG_D0 + REG1_16 (insn)] = load_mem ((State.regs[REG_A0 + REG0_16 (insn)] + ((insn & 0xffff) << 16) + extension), 1); } /* movbu (d8,sp), dn */ void OP_F8B800 (insn, extension) unsigned long insn, extension; { State.regs[REG_D0 + REG0_8 (insn)] = load_mem ((State.regs[REG_SP] + (insn & 0xff)), 1); } /* movbu (d16,sp), dn */ void OP_FAB80000 (insn, extension) unsigned long insn, extension; { State.regs[REG_D0 + REG0_16 (insn)] = load_mem ((State.regs[REG_SP] + (insn & 0xffff)), 1); } /* movbu (d32,sp), dn */ void OP_FCB80000 (insn, extension) unsigned long insn, extension; { State.regs[REG_D0 + REG0_16 (insn)] = load_mem (State.regs[REG_SP] + (((insn & 0xffff) << 16) + extension), 1); } /* movbu (di,am), dn */ void OP_F400 (insn, extension) unsigned long insn, extension; { State.regs[REG_D0 + REG0_4 (insn)] = load_mem ((State.regs[REG_A0 + REG0 (insn)] + State.regs[REG_D0 + REG1 (insn)]), 1); } /* movbu (abs16), dn */ void OP_340000 (insn, extension) unsigned long insn, extension; { State.regs[REG_D0 + REG0_16 (insn)] = load_mem ((insn & 0xffff), 1); } /* movbu (abs32), dn */ void OP_FCA80000 (insn, extension) unsigned long insn, extension; { State.regs[REG_D0 + REG0_16 (insn)] = load_mem ((((insn & 0xffff) << 16) + extension), 1); } /* movbu dm, (an) */ void OP_F050 (insn, extension) unsigned long insn, extension; { store_mem (State.regs[REG_A0 + REG0 (insn)], 1, State.regs[REG_D0 + REG1 (insn)]); } /* movbu dm, (d8,an) */ void OP_F85000 (insn, extension) unsigned long insn, extension; { store_mem ((State.regs[REG_A0 + REG0_8 (insn)] + SEXT8 (insn & 0xff)), 1, State.regs[REG_D0 + REG1_8 (insn)]); } /* movbu dm, (d16,an) */ void OP_FA500000 (insn, extension) unsigned long insn, extension; { store_mem ((State.regs[REG_A0 + REG0_16 (insn)] + SEXT16 (insn & 0xffff)), 1, State.regs[REG_D0 + REG1_16 (insn)]); } /* movbu dm, (d32,an) */ void OP_FC500000 (insn, extension) unsigned long insn, extension; { store_mem ((State.regs[REG_A0 + REG0_16 (insn)] + ((insn & 0xffff) << 16) + extension), 1, State.regs[REG_D0 + REG1_16 (insn)]); } /* movbu dm, (d8,sp) */ void OP_F89200 (insn, extension) unsigned long insn, extension; { store_mem (State.regs[REG_SP] + (insn & 0xff), 1, State.regs[REG_D0 + REG1_8 (insn)]); } /* movbu dm, (d16,sp) */ void OP_FA920000 (insn, extension) unsigned long insn, extension; { store_mem (State.regs[REG_SP] + (insn & 0xffff), 2, State.regs[REG_D0 + REG1_16 (insn)]); } /* movbu dm (d32,sp) */ void OP_FC920000 (insn, extension) unsigned long insn, extension; { store_mem (State.regs[REG_SP] + (((insn & 0xffff) << 16) + extension), 2, State.regs[REG_D0 + REG1_16 (insn)]); } /* movbu dm, (di,an) */ void OP_F440 (insn, extension) unsigned long insn, extension; { store_mem ((State.regs[REG_A0 + REG0 (insn)] + State.regs[REG_D0 + REG1 (insn)]), 1, State.regs[REG_D0 + REG0_4 (insn)]); } /* movbu dm, (abs16) */ void OP_20000 (insn, extension) unsigned long insn, extension; { store_mem ((insn & 0xffff), 1, State.regs[REG_D0 + REG1_16 (insn)]); } /* movbu dm, (abs32) */ void OP_FC820000 (insn, extension) unsigned long insn, extension; { store_mem ((((insn & 0xffff) << 16) + extension), 1, State.regs[REG_D0 + REG1_16 (insn)]); } /* movhu (am), dn */ void OP_F060 (insn, extension) unsigned long insn, extension; { State.regs[REG_D0 + REG1 (insn)] = load_mem (State.regs[REG_A0 + REG0 (insn)], 2); } /* movhu (d8,am), dn */ void OP_F86000 (insn, extension) unsigned long insn, extension; { State.regs[REG_D0 + REG1_8 (insn)] = load_mem ((State.regs[REG_A0 + REG0_8 (insn)] + SEXT8 (insn & 0xff)), 2); } /* movhu (d16,am), dn */ void OP_FA600000 (insn, extension) unsigned long insn, extension; { State.regs[REG_D0 + REG1_16 (insn)] = load_mem ((State.regs[REG_A0 + REG0_16 (insn)] + SEXT16 (insn & 0xffff)), 2); } /* movhu (d32,am), dn */ void OP_FC600000 (insn, extension) unsigned long insn, extension; { State.regs[REG_D0 + REG1_16 (insn)] = load_mem ((State.regs[REG_A0 + REG0_16 (insn)] + ((insn & 0xffff) << 16) + extension), 2); } /* movhu (d8,sp) dn */ void OP_F8BC00 (insn, extension) unsigned long insn, extension; { State.regs[REG_D0 + REG0_8 (insn)] = load_mem ((State.regs[REG_SP] + (insn & 0xff)), 2); } /* movhu (d16,sp), dn */ void OP_FABC0000 (insn, extension) unsigned long insn, extension; { State.regs[REG_D0 + REG0_16 (insn)] = load_mem ((State.regs[REG_SP] + (insn & 0xffff)), 2); } /* movhu (d32,sp), dn */ void OP_FCBC0000 (insn, extension) unsigned long insn, extension; { State.regs[REG_D0 + REG0_16 (insn)] = load_mem (State.regs[REG_SP] + (((insn & 0xffff) << 16) + extension), 2); } /* movhu (di,am), dn */ void OP_F480 (insn, extension) unsigned long insn, extension; { State.regs[REG_D0 + REG0_4 (insn)] = load_mem ((State.regs[REG_A0 + REG0 (insn)] + State.regs[REG_D0 + REG1 (insn)]), 2); } /* movhu (abs16), dn */ void OP_380000 (insn, extension) unsigned long insn, extension; { State.regs[REG_D0 + REG0_16 (insn)] = load_mem ((insn & 0xffff), 2); } /* movhu (abs32), dn */ void OP_FCAC0000 (insn, extension) unsigned long insn, extension; { State.regs[REG_D0 + REG0_16 (insn)] = load_mem ((((insn & 0xffff) << 16) + extension), 2); } /* movhu dm, (an) */ void OP_F070 (insn, extension) unsigned long insn, extension; { store_mem (State.regs[REG_A0 + REG0 (insn)], 2, State.regs[REG_D0 + REG1 (insn)]); } /* movhu dm, (d8,an) */ void OP_F87000 (insn, extension) unsigned long insn, extension; { store_mem ((State.regs[REG_A0 + REG0_8 (insn)] + SEXT8 (insn & 0xff)), 2, State.regs[REG_D0 + REG1_8 (insn)]); } /* movhu dm, (d16,an) */ void OP_FA700000 (insn, extension) unsigned long insn, extension; { store_mem ((State.regs[REG_A0 + REG0_16 (insn)] + SEXT16 (insn & 0xffff)), 2, State.regs[REG_D0 + REG1_16 (insn)]); } /* movhu dm, (d32,an) */ void OP_FC700000 (insn, extension) unsigned long insn, extension; { store_mem ((State.regs[REG_A0 + REG0_16 (insn)] + ((insn & 0xffff) << 16) + extension), 2, State.regs[REG_D0 + REG1_16 (insn)]); } /* movhu dm,(d8,sp) */ void OP_F89300 (insn, extension) unsigned long insn, extension; { store_mem (State.regs[REG_SP] + (insn & 0xff), 2, State.regs[REG_D0 + REG1_8 (insn)]); } /* movhu dm,(d16,sp) */ void OP_FA930000 (insn, extension) unsigned long insn, extension; { store_mem (State.regs[REG_SP] + (insn & 0xffff), 2, State.regs[REG_D0 + REG1_16 (insn)]); } /* movhu dm,(d32,sp) */ void OP_FC930000 (insn, extension) unsigned long insn, extension; { store_mem (State.regs[REG_SP] + (((insn & 0xffff) << 16) + extension), 2, State.regs[REG_D0 + REG1_16 (insn)]); } /* movhu dm, (di,an) */ void OP_F4C0 (insn, extension) unsigned long insn, extension; { store_mem ((State.regs[REG_A0 + REG0 (insn)] + State.regs[REG_D0 + REG1 (insn)]), 2, State.regs[REG_D0 + REG0_4 (insn)]); } /* movhu dm, (abs16) */ void OP_30000 (insn, extension) unsigned long insn, extension; { store_mem ((insn & 0xffff), 2, State.regs[REG_D0 + REG1_16 (insn)]); } /* movhu dm, (abs32) */ void OP_FC830000 (insn, extension) unsigned long insn, extension; { store_mem ((((insn & 0xffff) << 16) + extension), 2, State.regs[REG_D0 + REG1_16 (insn)]); } /* ext dn */ void OP_F2D0 (insn, extension) unsigned long insn, extension; { if (State.regs[REG_D0 + REG0 (insn)] & 0x80000000) State.regs[REG_MDR] = -1; else State.regs[REG_MDR] = 0; } /* extb dn */ void OP_10 (insn, extension) unsigned long insn, extension; { State.regs[REG_D0 + REG0 (insn)] = SEXT8 (State.regs[REG_D0 + REG0 (insn)]); } /* extbu dn */ void OP_14 (insn, extension) unsigned long insn, extension; { State.regs[REG_D0 + REG0 (insn)] &= 0xff; } /* exth dn */ void OP_18 (insn, extension) unsigned long insn, extension; { State.regs[REG_D0 + REG0 (insn)] = SEXT16 (State.regs[REG_D0 + REG0 (insn)]); } /* exthu dn */ void OP_1C (insn, extension) unsigned long insn, extension; { State.regs[REG_D0 + REG0 (insn)] &= 0xffff; } /* movm (sp), reg_list */ void OP_CE00 (insn, extension) unsigned long insn, extension; { unsigned long sp = State.regs[REG_SP]; unsigned long mask; mask = insn & 0xff; if (mask & 0x8) { sp += 4; State.regs[REG_LAR] = load_mem (sp, 4); sp += 4; State.regs[REG_LIR] = load_mem (sp, 4); sp += 4; State.regs[REG_MDR] = load_mem (sp, 4); sp += 4; State.regs[REG_A0 + 1] = load_mem (sp, 4); sp += 4; State.regs[REG_A0] = load_mem (sp, 4); sp += 4; State.regs[REG_D0 + 1] = load_mem (sp, 4); sp += 4; State.regs[REG_D0] = load_mem (sp, 4); sp += 4; } if (mask & 0x10) { State.regs[REG_A0 + 3] = load_mem (sp, 4); sp += 4; } if (mask & 0x20) { State.regs[REG_A0 + 2] = load_mem (sp, 4); sp += 4; } if (mask & 0x40) { State.regs[REG_D0 + 3] = load_mem (sp, 4); sp += 4; } if (mask & 0x80) { State.regs[REG_D0 + 2] = load_mem (sp, 4); sp += 4; } /* And make sure to update the stack pointer. */ State.regs[REG_SP] = sp; } /* movm reg_list, (sp) */ void OP_CF00 (insn, extension) unsigned long insn, extension; { unsigned long sp = State.regs[REG_SP]; unsigned long mask; mask = insn & 0xff; if (mask & 0x80) { sp -= 4; store_mem (sp, 4, State.regs[REG_D0 + 2]); } if (mask & 0x40) { sp -= 4; store_mem (sp, 4, State.regs[REG_D0 + 3]); } if (mask & 0x20) { sp -= 4; store_mem (sp, 4, State.regs[REG_A0 + 2]); } if (mask & 0x10) { sp -= 4; store_mem (sp, 4, State.regs[REG_A0 + 3]); } if (mask & 0x8) { sp -= 4; store_mem (sp, 4, State.regs[REG_D0]); sp -= 4; store_mem (sp, 4, State.regs[REG_D0 + 1]); sp -= 4; store_mem (sp, 4, State.regs[REG_A0]); sp -= 4; store_mem (sp, 4, State.regs[REG_A0 + 1]); sp -= 4; store_mem (sp, 4, State.regs[REG_MDR]); sp -= 4; store_mem (sp, 4, State.regs[REG_LIR]); sp -= 4; store_mem (sp, 4, State.regs[REG_LAR]); sp -= 4; } /* And make sure to update the stack pointer. */ State.regs[REG_SP] = sp; } /* clr dn */ void OP_0 (insn, extension) unsigned long insn, extension; { State.regs[REG_D0 + REG1 (insn)] = 0; PSW |= PSW_Z; PSW &= ~(PSW_V | PSW_C | PSW_N); } /* add dm,dn */ void OP_E0 (insn, extension) unsigned long insn, extension; { int z, c, n, v; unsigned long reg1, reg2, value; reg1 = State.regs[REG_D0 + REG1 (insn)]; reg2 = State.regs[REG_D0 + REG0 (insn)]; value = reg1 + reg2; State.regs[REG_D0 + REG0 (insn)] = value; z = (value == 0); n = (value & 0x80000000); c = (value < reg1) || (value < reg2); v = ((reg2 & 0x80000000) == (reg1 & 0x80000000) && (reg2 & 0x80000000) != (value & 0x80000000)); PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0) | (c ? PSW_C : 0) | (v ? PSW_V : 0)); } /* add dm, an */ void OP_F160 (insn, extension) unsigned long insn, extension; { int z, c, n, v; unsigned long reg1, reg2, value; reg1 = State.regs[REG_D0 + REG1 (insn)]; reg2 = State.regs[REG_A0 + REG0 (insn)]; value = reg1 + reg2; State.regs[REG_A0 + REG0 (insn)] = value; z = (value == 0); n = (value & 0x80000000); c = (value < reg1) || (value < reg2); v = ((reg2 & 0x80000000) == (reg1 & 0x80000000) && (reg2 & 0x80000000) != (value & 0x80000000)); PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0) | (c ? PSW_C : 0) | (v ? PSW_V : 0)); } /* add am, dn */ void OP_F150 (insn, extension) unsigned long insn, extension; { int z, c, n, v; unsigned long reg1, reg2, value; reg1 = State.regs[REG_A0 + REG1 (insn)]; reg2 = State.regs[REG_D0 + REG0 (insn)]; value = reg1 + reg2; State.regs[REG_D0 + REG0 (insn)] = value; z = (value == 0); n = (value & 0x80000000); c = (value < reg1) || (value < reg2); v = ((reg2 & 0x80000000) == (reg1 & 0x80000000) && (reg2 & 0x80000000) != (value & 0x80000000)); PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0) | (c ? PSW_C : 0) | (v ? PSW_V : 0)); } /* add am,an */ void OP_F170 (insn, extension) unsigned long insn, extension; { int z, c, n, v; unsigned long reg1, reg2, value; reg1 = State.regs[REG_A0 + REG1 (insn)]; reg2 = State.regs[REG_A0 + REG0 (insn)]; value = reg1 + reg2; State.regs[REG_A0 + REG0 (insn)] = value; z = (value == 0); n = (value & 0x80000000); c = (value < reg1) || (value < reg2); v = ((reg2 & 0x80000000) == (reg1 & 0x80000000) && (reg2 & 0x80000000) != (value & 0x80000000)); PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0) | (c ? PSW_C : 0) | (v ? PSW_V : 0)); } /* add imm8, dn */ void OP_2800 (insn, extension) unsigned long insn, extension; { int z, c, n, v; unsigned long reg1, imm, value; reg1 = State.regs[REG_D0 + REG0_8 (insn)]; imm = SEXT8 (insn & 0xff); value = reg1 + imm; State.regs[REG_D0 + REG0_8 (insn)] = value; z = (value == 0); n = (value & 0x80000000); c = (value < reg1) || (value < imm); v = ((reg1 & 0x80000000) == (imm & 0x80000000) && (reg1 & 0x80000000) != (value & 0x80000000)); PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0) | (c ? PSW_C : 0) | (v ? PSW_V : 0)); } /* add imm16, dn */ void OP_FAC00000 (insn, extension) unsigned long insn, extension; { int z, c, n, v; unsigned long reg1, imm, value; reg1 = State.regs[REG_D0 + REG0_16 (insn)]; imm = SEXT16 (insn & 0xffff); value = reg1 + imm; State.regs[REG_D0 + REG0_16 (insn)] = value; z = (value == 0); n = (value & 0x80000000); c = (value < reg1) || (value < imm); v = ((reg1 & 0x80000000) == (imm & 0x80000000) && (reg1 & 0x80000000) != (value & 0x80000000)); PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0) | (c ? PSW_C : 0) | (v ? PSW_V : 0)); } /* add imm32,dn */ void OP_FCC00000 (insn, extension) unsigned long insn, extension; { int z, c, n, v; unsigned long reg1, imm, value; reg1 = State.regs[REG_D0 + REG0_16 (insn)]; imm = ((insn & 0xffff) << 16) + extension; value = reg1 + imm; State.regs[REG_D0 + REG0_16 (insn)] = value; z = (value == 0); n = (value & 0x80000000); c = (value < reg1) || (value < imm); v = ((reg1 & 0x80000000) == (imm & 0x80000000) && (reg1 & 0x80000000) != (value & 0x80000000)); PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0) | (c ? PSW_C : 0) | (v ? PSW_V : 0)); } /* add imm8, an */ void OP_2000 (insn, extension) unsigned long insn, extension; { int z, c, n, v; unsigned long reg1, imm, value; reg1 = State.regs[REG_A0 + REG0_8 (insn)]; imm = SEXT8 (insn & 0xff); value = reg1 + imm; State.regs[REG_A0 + REG0_8 (insn)] = value; z = (value == 0); n = (value & 0x80000000); c = (value < reg1) || (value < imm); v = ((reg1 & 0x80000000) == (imm & 0x80000000) && (reg1 & 0x80000000) != (value & 0x80000000)); PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0) | (c ? PSW_C : 0) | (v ? PSW_V : 0)); } /* add imm16, an */ void OP_FAD00000 (insn, extension) unsigned long insn, extension; { int z, c, n, v; unsigned long reg1, imm, value; reg1 = State.regs[REG_A0 + REG0_16 (insn)]; imm = SEXT16 (insn & 0xffff); value = reg1 + imm; State.regs[REG_A0 + REG0_16 (insn)] = value; z = (value == 0); n = (value & 0x80000000); c = (value < reg1) || (value < imm); v = ((reg1 & 0x80000000) == (imm & 0x80000000) && (reg1 & 0x80000000) != (value & 0x80000000)); PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0) | (c ? PSW_C : 0) | (v ? PSW_V : 0)); } /* add imm32, an */ void OP_FCD00000 (insn, extension) unsigned long insn, extension; { int z, c, n, v; unsigned long reg1, imm, value; reg1 = State.regs[REG_A0 + REG0_16 (insn)]; imm = ((insn & 0xffff) << 16) + extension; value = reg1 + imm; State.regs[REG_A0 + REG0_16 (insn)] = value; z = (value == 0); n = (value & 0x80000000); c = (value < reg1) || (value < imm); v = ((reg1 & 0x80000000) == (imm & 0x80000000) && (reg1 & 0x80000000) != (value & 0x80000000)); PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0) | (c ? PSW_C : 0) | (v ? PSW_V : 0)); } /* add imm8, sp */ void OP_F8FE00 (insn, extension) unsigned long insn, extension; { unsigned long reg1, imm, value; reg1 = State.regs[REG_SP]; imm = SEXT8 (insn & 0xff); value = reg1 + imm; State.regs[REG_SP] = value; } /* add imm16,sp */ void OP_FAFE0000 (insn, extension) unsigned long insn, extension; { unsigned long reg1, imm, value; reg1 = State.regs[REG_SP]; imm = SEXT16 (insn & 0xffff); value = reg1 + imm; State.regs[REG_SP] = value; } /* add imm32, sp */ void OP_FCFE0000 (insn, extension) unsigned long insn, extension; { unsigned long reg1, imm, value; reg1 = State.regs[REG_SP]; imm = ((insn & 0xffff) << 16) + extension; value = reg1 + imm; State.regs[REG_SP] = value; } /* addc dm,dn */ void OP_F140 (insn, extension) unsigned long insn, extension; { int z, c, n, v; unsigned long reg1, reg2, value; reg1 = State.regs[REG_D0 + REG1 (insn)]; reg2 = State.regs[REG_D0 + REG0 (insn)]; value = reg1 + reg2 + ((PSW & PSW_C) != 0); State.regs[REG_D0 + REG0 (insn)] = value; z = (value == 0); n = (value & 0x80000000); c = (value < reg1) || (value < reg2); v = ((reg2 & 0x80000000) == (reg1 & 0x80000000) && (reg2 & 0x80000000) != (value & 0x80000000)); PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0) | (c ? PSW_C : 0) | (v ? PSW_V : 0)); } /* sub dm, dn */ void OP_F100 (insn, extension) unsigned long insn, extension; { int z, c, n, v; unsigned long reg1, reg2, value; reg1 = State.regs[REG_D0 + REG1 (insn)]; reg2 = State.regs[REG_D0 + REG0 (insn)]; value = reg2 - reg1; State.regs[REG_D0 + REG0 (insn)] = value; z = (value == 0); n = (value & 0x80000000); c = (reg1 > reg2); v = ((reg2 & 0x80000000) != (reg1 & 0x80000000) && (reg2 & 0x80000000) != (value & 0x80000000)); PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0) | (c ? PSW_C : 0) | (v ? PSW_V : 0)); } /* sub dm, an */ void OP_F120 (insn, extension) unsigned long insn, extension; { int z, c, n, v; unsigned long reg1, reg2, value; reg1 = State.regs[REG_D0 + REG1 (insn)]; reg2 = State.regs[REG_A0 + REG0 (insn)]; value = reg2 - reg1; State.regs[REG_A0 + REG0 (insn)] = value; z = (value == 0); n = (value & 0x80000000); c = (reg1 > reg2); v = ((reg2 & 0x80000000) != (reg1 & 0x80000000) && (reg2 & 0x80000000) != (value & 0x80000000)); PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0) | (c ? PSW_C : 0) | (v ? PSW_V : 0)); } /* sub am, dn */ void OP_F110 (insn, extension) unsigned long insn, extension; { int z, c, n, v; unsigned long reg1, reg2, value; reg1 = State.regs[REG_A0 + REG1 (insn)]; reg2 = State.regs[REG_D0 + REG0 (insn)]; value = reg2 - reg1; State.regs[REG_D0 + REG0 (insn)] = value; z = (value == 0); n = (value & 0x80000000); c = (reg1 > reg2); v = ((reg2 & 0x80000000) != (reg1 & 0x80000000) && (reg2 & 0x80000000) != (value & 0x80000000)); PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0) | (c ? PSW_C : 0) | (v ? PSW_V : 0)); } /* sub am, an */ void OP_F130 (insn, extension) unsigned long insn, extension; { int z, c, n, v; unsigned long reg1, reg2, value; reg1 = State.regs[REG_A0 + REG1 (insn)]; reg2 = State.regs[REG_A0 + REG0 (insn)]; value = reg2 - reg1; State.regs[REG_A0 + REG0 (insn)] = value; z = (value == 0); n = (value & 0x80000000); c = (reg1 > reg2); v = ((reg2 & 0x80000000) != (reg1 & 0x80000000) && (reg2 & 0x80000000) != (value & 0x80000000)); PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0) | (c ? PSW_C : 0) | (v ? PSW_V : 0)); } /* sub imm32, dn */ void OP_FCC40000 (insn, extension) unsigned long insn, extension; { int z, c, n, v; unsigned long reg1, imm, value; reg1 = State.regs[REG_D0 + REG0_16 (insn)]; imm = ((insn & 0xffff) << 16) + extension; value = reg1 - imm; State.regs[REG_D0 + REG0_16 (insn)] = value; z = (value == 0); n = (value & 0x80000000); c = (reg1 < imm); v = ((reg1 & 0x80000000) != (imm & 0x80000000) && (reg1 & 0x80000000) != (value & 0x80000000)); PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0) | (c ? PSW_C : 0) | (v ? PSW_V : 0)); } /* sub imm32, an */ void OP_FCD40000 (insn, extension) unsigned long insn, extension; { int z, c, n, v; unsigned long reg1, imm, value; reg1 = State.regs[REG_A0 + REG0_16 (insn)]; imm = ((insn & 0xffff) << 16) + extension; value = reg1 - imm; State.regs[REG_A0 + REG0_16 (insn)] = value; z = (value == 0); n = (value & 0x80000000); c = (reg1 < imm); v = ((reg1 & 0x80000000) != (imm & 0x80000000) && (reg1 & 0x80000000) != (value & 0x80000000)); PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0) | (c ? PSW_C : 0) | (v ? PSW_V : 0)); } /* subc dm, dn */ void OP_F180 (insn, extension) unsigned long insn, extension; { int z, c, n, v; unsigned long reg1, reg2, value; reg1 = State.regs[REG_D0 + REG1 (insn)]; reg2 = State.regs[REG_D0 + REG0 (insn)]; value = reg2 - reg1 - ((PSW & PSW_C) != 0); State.regs[REG_D0 + REG0 (insn)] = value; z = (value == 0); n = (value & 0x80000000); c = (reg1 > reg2); v = ((reg2 & 0x80000000) != (reg1 & 0x80000000) && (reg2 & 0x80000000) != (value & 0x80000000)); PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0) | (c ? PSW_C : 0) | (v ? PSW_V : 0)); } /* mul dm, dn */ void OP_F240 (insn, extension) unsigned long insn, extension; { unsigned long long temp; int n, z; temp = ((signed long)State.regs[REG_D0 + REG0 (insn)] * (signed long)State.regs[REG_D0 + REG1 (insn)]); State.regs[REG_D0 + REG0 (insn)] = temp & 0xffffffff; State.regs[REG_MDR] = (temp & 0xffffffff00000000LL) >> 32;; z = (State.regs[REG_D0 + REG0 (insn)] == 0); n = (State.regs[REG_D0 + REG0 (insn)] & 0x80000000) != 0; PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0)); } /* mulu dm, dn */ void OP_F250 (insn, extension) unsigned long insn, extension; { unsigned long long temp; int n, z; temp = (State.regs[REG_D0 + REG0 (insn)] * State.regs[REG_D0 + REG1 (insn)]); State.regs[REG_D0 + REG0 (insn)] = temp & 0xffffffff; State.regs[REG_MDR] = (temp & 0xffffffff00000000LL) >> 32; z = (State.regs[REG_D0 + REG0 (insn)] == 0); n = (State.regs[REG_D0 + REG0 (insn)] & 0x80000000) != 0; PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0)); } /* div dm, dn */ void OP_F260 (insn, extension) unsigned long insn, extension; { long long temp; int n, z; temp = State.regs[REG_MDR]; temp <<= 32; temp |= State.regs[REG_D0 + REG0 (insn)]; State.regs[REG_MDR] = temp % (long)State.regs[REG_D0 + REG1 (insn)]; temp /= (long)State.regs[REG_D0 + REG1 (insn)]; State.regs[REG_D0 + REG0 (insn)] = temp & 0xffffffff; z = (State.regs[REG_D0 + REG0 (insn)] == 0); n = (State.regs[REG_D0 + REG0 (insn)] & 0x80000000) != 0; PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0)); } /* divu dm, dn */ void OP_F270 (insn, extension) unsigned long insn, extension; { unsigned long long temp; int n, z; temp = State.regs[REG_MDR]; temp <<= 32; temp |= State.regs[REG_D0 + REG0 (insn)]; State.regs[REG_MDR] = temp % State.regs[REG_D0 + REG1 (insn)]; temp /= State.regs[REG_D0 + REG1 (insn)]; State.regs[REG_D0 + REG0 (insn)] = temp & 0xffffffff; z = (State.regs[REG_D0 + REG0 (insn)] == 0); n = (State.regs[REG_D0 + REG0 (insn)] & 0x80000000) != 0; PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0)); } /* inc dn */ void OP_40 (insn, extension) unsigned long insn, extension; { int z,n,c,v; unsigned int value, imm, reg1; reg1 = State.regs[REG_D0 + REG1 (insn)]; imm = 1; value = reg1 + imm; State.regs[REG_D0 + REG1 (insn)] = value; z = (value == 0); n = (value & 0x80000000); c = (reg1 < imm); v = ((reg1 & 0x80000000) == (imm & 0x80000000) && (reg1 & 0x80000000) != (value & 0x80000000)); PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0) | (c ? PSW_C : 0) | (v ? PSW_V : 0)); } /* inc an */ void OP_41 (insn, extension) unsigned long insn, extension; { State.regs[REG_A0 + REG1 (insn)] += 1; } /* inc4 an */ void OP_50 (insn, extension) unsigned long insn, extension; { State.regs[REG_A0 + REG0 (insn)] += 4; } /* cmp imm8, dn */ void OP_A000 (insn, extension) unsigned long insn, extension; { int z, c, n, v; unsigned long reg1, imm, value; reg1 = State.regs[REG_D0 + REG0_8 (insn)]; imm = SEXT8 (insn & 0xff); value = reg1 - imm; z = (value == 0); n = (value & 0x80000000); c = (reg1 < imm); v = ((reg1 & 0x80000000) != (imm & 0x80000000) && (reg1 & 0x80000000) != (value & 0x80000000)); PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0) | (c ? PSW_C : 0) | (v ? PSW_V : 0)); } /* cmp dm, dn */ void OP_A0 (insn, extension) unsigned long insn, extension; { int z, c, n, v; unsigned long reg1, reg2, value; reg1 = State.regs[REG_D0 + REG1 (insn)]; reg2 = State.regs[REG_D0 + REG0 (insn)]; value = reg2 - reg1; z = (value == 0); n = (value & 0x80000000); c = (reg1 > reg2); v = ((reg2 & 0x80000000) != (reg1 & 0x80000000) && (reg2 & 0x80000000) != (value & 0x80000000)); PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0) | (c ? PSW_C : 0) | (v ? PSW_V : 0)); } /* cmp dm, an */ void OP_F1A0 (insn, extension) unsigned long insn, extension; { int z, c, n, v; unsigned long reg1, reg2, value; reg1 = State.regs[REG_D0 + REG1 (insn)]; reg2 = State.regs[REG_A0 + REG0 (insn)]; value = reg2 - reg1; z = (value == 0); n = (value & 0x80000000); c = (reg1 > reg2); v = ((reg2 & 0x80000000) != (reg1 & 0x80000000) && (reg2 & 0x80000000) != (value & 0x80000000)); PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0) | (c ? PSW_C : 0) | (v ? PSW_V : 0)); } /* cmp am, dn */ void OP_F190 (insn, extension) unsigned long insn, extension; { int z, c, n, v; unsigned long reg1, reg2, value; reg1 = State.regs[REG_A0 + REG1 (insn)]; reg2 = State.regs[REG_D0 + REG0 (insn)]; value = reg2 - reg1; z = (value == 0); n = (value & 0x80000000); c = (reg1 > reg2); v = ((reg2 & 0x80000000) != (reg1 & 0x80000000) && (reg2 & 0x80000000) != (value & 0x80000000)); PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0) | (c ? PSW_C : 0) | (v ? PSW_V : 0)); } /* cmp imm8, an */ void OP_B000 (insn, extension) unsigned long insn, extension; { int z, c, n, v; unsigned long reg1, imm, value; reg1 = State.regs[REG_A0 + REG0_8 (insn)]; imm = insn & 0xff; value = reg1 - imm; z = (value == 0); n = (value & 0x80000000); c = (reg1 < imm); v = ((reg1 & 0x80000000) != (imm & 0x80000000) && (reg1 & 0x80000000) != (value & 0x80000000)); PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0) | (c ? PSW_C : 0) | (v ? PSW_V : 0)); } /* cmp am, an */ void OP_B0 (insn, extension) unsigned long insn, extension; { int z, c, n, v; unsigned long reg1, reg2, value; reg1 = State.regs[REG_A0 + REG1 (insn)]; reg2 = State.regs[REG_A0 + REG0 (insn)]; value = reg2 - reg1; z = (value == 0); n = (value & 0x80000000); c = (reg1 > reg2); v = ((reg2 & 0x80000000) != (reg1 & 0x80000000) && (reg2 & 0x80000000) != (value & 0x80000000)); PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0) | (c ? PSW_C : 0) | (v ? PSW_V : 0)); } /* cmp imm16, dn */ void OP_FAC80000 (insn, extension) unsigned long insn, extension; { int z, c, n, v; unsigned long reg1, imm, value; reg1 = State.regs[REG_D0 + REG0_16 (insn)]; imm = SEXT16 (insn & 0xffff); value = reg1 - imm; z = (value == 0); n = (value & 0x80000000); c = (reg1 < imm); v = ((reg1 & 0x80000000) != (imm & 0x80000000) && (reg1 & 0x80000000) != (value & 0x80000000)); PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0) | (c ? PSW_C : 0) | (v ? PSW_V : 0)); } /* cmp imm32, dn */ void OP_FCC80000 (insn, extension) unsigned long insn, extension; { int z, c, n, v; unsigned long reg1, imm, value; reg1 = State.regs[REG_D0 + REG0_16 (insn)]; imm = ((insn & 0xffff) << 16) + extension; value = reg1 - imm; z = (value == 0); n = (value & 0x80000000); c = (reg1 < imm); v = ((reg1 & 0x80000000) != (imm & 0x80000000) && (reg1 & 0x80000000) != (value & 0x80000000)); PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0) | (c ? PSW_C : 0) | (v ? PSW_V : 0)); } /* cmp imm16, an */ void OP_FAD80000 (insn, extension) unsigned long insn, extension; { int z, c, n, v; unsigned long reg1, imm, value; reg1 = State.regs[REG_A0 + REG0_16 (insn)]; imm = insn & 0xffff; value = reg1 - imm; z = (value == 0); n = (value & 0x80000000); c = (reg1 < imm); v = ((reg1 & 0x80000000) != (imm & 0x80000000) && (reg1 & 0x80000000) != (value & 0x80000000)); PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0) | (c ? PSW_C : 0) | (v ? PSW_V : 0)); } /* cmp imm32, an */ void OP_FCD80000 (insn, extension) unsigned long insn, extension; { int z, c, n, v; unsigned long reg1, imm, value; reg1 = State.regs[REG_A0 + REG0_16 (insn)]; imm = ((insn & 0xffff) << 16) + extension; value = reg1 - imm; z = (value == 0); n = (value & 0x80000000); c = (reg1 < imm); v = ((reg1 & 0x80000000) != (imm & 0x80000000) && (reg1 & 0x80000000) != (value & 0x80000000)); PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0) | (c ? PSW_C : 0) | (v ? PSW_V : 0)); } /* and dm, dn */ void OP_F200 (insn, extension) unsigned long insn, extension; { int n, z; State.regs[REG_D0 + REG0 (insn)] &= State.regs[REG_D0 + REG1 (insn)]; z = (State.regs[REG_D0 + REG0 (insn)] == 0); n = (State.regs[REG_D0 + REG0 (insn)] & 0x80000000) != 0; PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0)); } /* and imm8, dn */ void OP_F8E000 (insn, extension) unsigned long insn, extension; { int n, z; State.regs[REG_D0 + REG0_8 (insn)] &= (insn & 0xff); z = (State.regs[REG_D0 + REG0_8 (insn)] == 0); n = (State.regs[REG_D0 + REG0_8 (insn)] & 0x80000000) != 0; PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0)); } /* and imm16, dn */ void OP_FAE00000 (insn, extension) unsigned long insn, extension; { int n, z; State.regs[REG_D0 + REG0_16 (insn)] &= (insn & 0xffff); z = (State.regs[REG_D0 + REG0_16 (insn)] == 0); n = (State.regs[REG_D0 + REG0_16 (insn)] & 0x80000000) != 0; PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0)); } /* and imm32, dn */ void OP_FCE00000 (insn, extension) unsigned long insn, extension; { int n, z; State.regs[REG_D0 + REG0_16 (insn)] &= ((insn & 0xffff) << 16) + extension; z = (State.regs[REG_D0 + REG0_16 (insn)] == 0); n = (State.regs[REG_D0 + REG0_16 (insn)] & 0x80000000) != 0; PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0)); } /* and imm16, psw */ void OP_FAFC0000 (insn, extension) unsigned long insn, extension; { PSW &= (insn & 0xffff); } /* or dm, dn*/ void OP_F210 (insn, extension) unsigned long insn, extension; { int n, z; State.regs[REG_D0 + REG0 (insn)] |= State.regs[REG_D0 + REG1 (insn)]; z = (State.regs[REG_D0 + REG0 (insn)] == 0); n = (State.regs[REG_D0 + REG0 (insn)] & 0x80000000) != 0; PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0)); } /* or imm8, dn */ void OP_F8E400 (insn, extension) unsigned long insn, extension; { int n, z; State.regs[REG_D0 + REG0_8 (insn)] |= insn & 0xff; z = (State.regs[REG_D0 + REG0_8 (insn)] == 0); n = (State.regs[REG_D0 + REG0_8 (insn)] & 0x80000000) != 0; PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0)); } /* or imm16, dn*/ void OP_FAE40000 (insn, extension) unsigned long insn, extension; { int n, z; State.regs[REG_D0 + REG0_16 (insn)] |= insn & 0xffff; z = (State.regs[REG_D0 + REG0_16 (insn)] == 0); n = (State.regs[REG_D0 + REG0_16 (insn)] & 0x80000000) != 0; PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0)); } /* or imm32, dn */ void OP_FCE40000 (insn, extension) unsigned long insn, extension; { int n, z; State.regs[REG_D0 + REG0_16 (insn)] |= ((insn & 0xffff) << 16) + extension; z = (State.regs[REG_D0 + REG0_16 (insn)] == 0); n = (State.regs[REG_D0 + REG0_16 (insn)] & 0x80000000) != 0; PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0)); } /* or imm16,psw */ void OP_FAFD0000 (insn, extension) unsigned long insn, extension; { PSW |= (insn & 0xffff); } /* xor dm, dn */ void OP_F220 (insn, extension) unsigned long insn, extension; { int n, z; State.regs[REG_D0 + REG0 (insn)] ^= State.regs[REG_D0 + REG1 (insn)]; z = (State.regs[REG_D0 + REG0 (insn)] == 0); n = (State.regs[REG_D0 + REG0 (insn)] & 0x80000000) != 0; PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0)); } /* xor imm16, dn */ void OP_FAE80000 (insn, extension) unsigned long insn, extension; { int n, z; State.regs[REG_D0 + REG0_16 (insn)] ^= insn & 0xffff; z = (State.regs[REG_D0 + REG0_16 (insn)] == 0); n = (State.regs[REG_D0 + REG0_16 (insn)] & 0x80000000) != 0; PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0)); } /* xor imm32, dn */ void OP_FCE80000 (insn, extension) unsigned long insn, extension; { int n, z; State.regs[REG_D0 + REG0_16 (insn)] ^= ((insn & 0xffff) << 16) + extension; z = (State.regs[REG_D0 + REG0_16 (insn)] == 0); n = (State.regs[REG_D0 + REG0_16 (insn)] & 0x80000000) != 0; PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0)); } /* not dn */ void OP_F230 (insn, extension) unsigned long insn, extension; { int n, z; State.regs[REG_D0 + REG0 (insn)] = ~State.regs[REG_D0 + REG0 (insn)]; z = (State.regs[REG_D0 + REG0 (insn)] == 0); n = (State.regs[REG_D0 + REG0 (insn)] & 0x80000000) != 0; PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0)); } /* btst imm8, dn */ void OP_F8EC00 (insn, extension) unsigned long insn, extension; { unsigned long temp; int z, n; temp = State.regs[REG_D0 + REG0_8 (insn)]; temp &= (insn & 0xff); n = (temp & 0x80000000) != 0; z = (temp == 0); PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= (z ? PSW_Z : 0) | (n ? PSW_N : 0); } /* btst imm16, dn */ void OP_FAEC0000 (insn, extension) unsigned long insn, extension; { unsigned long temp; int z, n; temp = State.regs[REG_D0 + REG0_16 (insn)]; temp &= (insn & 0xffff); n = (temp & 0x80000000) != 0; z = (temp == 0); PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= (z ? PSW_Z : 0) | (n ? PSW_N : 0); } /* btst imm32, dn */ void OP_FCEC0000 (insn, extension) unsigned long insn, extension; { unsigned long temp; int z, n; temp = State.regs[REG_D0 + REG0_16 (insn)]; temp &= ((insn & 0xffff) << 16) + extension; n = (temp & 0x80000000) != 0; z = (temp == 0); PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= (z ? PSW_Z : 0) | (n ? PSW_N : 0); } /* btst imm8,(abs32) */ void OP_FE020000 (insn, extension) unsigned long insn, extension; { unsigned long temp; int n, z; temp = load_mem (((insn & 0xffff) << 16) | (extension >> 8), 1); temp &= (extension & 0xff); n = (temp & 0x80000000) != 0; z = (temp == 0); PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= (z ? PSW_Z : 0) | (n ? PSW_N : 0); } /* btst imm8,(d8,an) */ void OP_FAF80000 (insn, extension) unsigned long insn, extension; { unsigned long temp; int n, z; temp = load_mem ((State.regs[REG_A0 + REG0_16 (insn)] + SEXT8 ((insn & 0xff00) >> 8)), 1); temp &= (insn & 0xff); n = (temp & 0x80000000) != 0; z = (temp == 0); PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= (z ? PSW_Z : 0) | (n ? PSW_N : 0); } /* bset dm, (an) */ void OP_F080 (insn, extension) unsigned long insn, extension; { unsigned long temp; int z; temp = load_mem (State.regs[REG_A0 + REG0 (insn)], 1); z = (temp & State.regs[REG_D0 + REG1 (insn)]) == 0; temp |= State.regs[REG_D0 + REG1 (insn)]; store_mem (State.regs[REG_A0 + REG0 (insn)], 1, temp); PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= (z ? PSW_Z : 0); } /* bset imm8, (abs32) */ void OP_FE000000 (insn, extension) unsigned long insn, extension; { unsigned long temp; int z; temp = load_mem (((insn & 0xffff) << 16 | (extension >> 8)), 1); z = (temp & (extension & 0xff)) == 0; temp |= (extension & 0xff); store_mem ((((insn & 0xffff) << 16) | (extension >> 8)), 1, temp); PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= (z ? PSW_Z : 0); } /* bset imm8,(d8,an) */ void OP_FAF00000 (insn, extension) unsigned long insn, extension; { unsigned long temp; int z; temp = load_mem ((State.regs[REG_A0 + REG0_16 (insn)] + SEXT8 ((insn & 0xff00) >> 8)), 1); z = (temp & (insn & 0xff)) == 0; temp |= (insn & 0xff); store_mem ((State.regs[REG_A0 + REG0_16 (insn)] + SEXT8 ((insn & 0xff00) >> 8)), 1, temp); PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= (z ? PSW_Z : 0); } /* bclr dm, (an) */ void OP_F090 (insn, extension) unsigned long insn, extension; { unsigned long temp; int z; temp = load_mem (State.regs[REG_A0 + REG0 (insn)], 1); z = (temp & State.regs[REG_D0 + REG1 (insn)]) == 0; temp = temp & ~State.regs[REG_D0 + REG1 (insn)]; store_mem (State.regs[REG_A0 + REG0 (insn)], 1, temp); PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= (z ? PSW_Z : 0); } /* bclr imm8, (abs32) */ void OP_FE010000 (insn, extension) unsigned long insn, extension; { unsigned long temp; int z; temp = load_mem (((insn & 0xffff) << 16) | (extension >> 8), 1); z = (temp & (extension & 0xff)) == 0; temp = temp & ~(extension & 0xff); store_mem (((insn & 0xffff) << 16) | (extension >> 8), 1, temp); PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= (z ? PSW_Z : 0); } /* bclr imm8,(d8,an) */ void OP_FAF40000 (insn, extension) unsigned long insn, extension; { unsigned long temp; int z; temp = load_mem ((State.regs[REG_A0 + REG0_16 (insn)] + SEXT8 ((insn & 0xff00) >> 8)), 1); z = (temp & (insn & 0xff)) == 0; temp = temp & ~(insn & 0xff); store_mem ((State.regs[REG_A0 + REG0_16 (insn)] + SEXT8 ((insn & 0xff00) >> 8)), 1, temp); PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= (z ? PSW_Z : 0); } /* asr dm, dn */ void OP_F2B0 (insn, extension) unsigned long insn, extension; { long temp; int z, n, c; temp = State.regs[REG_D0 + REG0 (insn)]; c = temp & 1; temp >>= State.regs[REG_D0 + REG1 (insn)]; State.regs[REG_D0 + REG0 (insn)] = temp; z = (State.regs[REG_D0 + REG0 (insn)] == 0); n = (State.regs[REG_D0 + REG0 (insn)] & 0x80000000) != 0; PSW &= ~(PSW_Z | PSW_N | PSW_C); PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0) | (c ? PSW_C : 0)); } /* asr imm8, dn */ void OP_F8C800 (insn, extension) unsigned long insn, extension; { long temp; int z, n, c; temp = State.regs[REG_D0 + REG0_8 (insn)]; c = temp & 1; temp >>= (insn & 0xff); State.regs[REG_D0 + REG0_8 (insn)] = temp; z = (State.regs[REG_D0 + REG0_8 (insn)] == 0); n = (State.regs[REG_D0 + REG0_8 (insn)] & 0x80000000) != 0; PSW &= ~(PSW_Z | PSW_N | PSW_C); PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0) | (c ? PSW_C : 0)); } /* lsr dm, dn */ void OP_F2A0 (insn, extension) unsigned long insn, extension; { int z, n, c; c = State.regs[REG_D0 + REG0 (insn)] & 1; State.regs[REG_D0 + REG0 (insn)] >>= State.regs[REG_D0 + REG1 (insn)]; z = (State.regs[REG_D0 + REG0 (insn)] == 0); n = (State.regs[REG_D0 + REG0 (insn)] & 0x80000000) != 0; PSW &= ~(PSW_Z | PSW_N | PSW_C); PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0) | (c ? PSW_C : 0)); } /* lsr imm8, dn */ void OP_F8C400 (insn, extension) unsigned long insn, extension; { int z, n, c; c = State.regs[REG_D0 + REG0_8 (insn)] & 1; State.regs[REG_D0 + REG0_8 (insn)] >>= (insn & 0xff); z = (State.regs[REG_D0 + REG0_8 (insn)] == 0); n = (State.regs[REG_D0 + REG0_8 (insn)] & 0x80000000) != 0; PSW &= ~(PSW_Z | PSW_N | PSW_C); PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0) | (c ? PSW_C : 0)); } /* asl dm, dn */ void OP_F290 (insn, extension) unsigned long insn, extension; { int n, z; State.regs[REG_D0 + REG0 (insn)] <<= State.regs[REG_D0 + REG1 (insn)]; z = (State.regs[REG_D0 + REG0 (insn)] == 0); n = (State.regs[REG_D0 + REG0 (insn)] & 0x80000000) != 0; PSW &= ~(PSW_Z | PSW_N); PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0)); } /* asl imm8, dn */ void OP_F8C000 (insn, extension) unsigned long insn, extension; { int n, z; State.regs[REG_D0 + REG0_8 (insn)] <<= (insn & 0xff); z = (State.regs[REG_D0 + REG0_8 (insn)] == 0); n = (State.regs[REG_D0 + REG0_8 (insn)] & 0x80000000) != 0; PSW &= ~(PSW_Z | PSW_N); PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0)); } /* asl2 dn */ void OP_54 (insn, extension) unsigned long insn, extension; { int n, z; State.regs[REG_D0 + REG0 (insn)] <<= 2; z = (State.regs[REG_D0 + REG0 (insn)] == 0); n = (State.regs[REG_D0 + REG0 (insn)] & 0x80000000) != 0; PSW &= ~(PSW_Z | PSW_N); PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0)); } /* ror dn */ void OP_F284 (insn, extension) unsigned long insn, extension; { unsigned long value; int c,n,z; value = State.regs[REG_D0 + REG0 (insn)]; c = (value & 0x1); value >>= 1; value |= ((PSW & PSW_C) != 0) ? 0x80000000 : 0; State.regs[REG_D0 + REG0 (insn)] = value; z = (value == 0); n = (value & 0x80000000) != 0; PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0) | (c ? PSW_C : 0)); } /* rol dn */ void OP_F280 (insn, extension) unsigned long insn, extension; { unsigned long value; int c,n,z; value = State.regs[REG_D0 + REG0 (insn)]; c = (value & 0x80000000) ? 1 : 0; value <<= 1; value |= ((PSW & PSW_C) != 0); State.regs[REG_D0 + REG0 (insn)] = value; z = (value == 0); n = (value & 0x80000000) != 0; PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0) | (c ? PSW_C : 0)); } /* beq label:8 */ void OP_C800 (insn, extension) unsigned long insn, extension; { /* The dispatching code will add 2 after we return, so we subtract two here to make things right. */ if (PSW & PSW_Z) State.regs[REG_PC] += SEXT8 (insn & 0xff) - 2; } /* bne label:8 */ void OP_C900 (insn, extension) unsigned long insn, extension; { /* The dispatching code will add 2 after we return, so we subtract two here to make things right. */ if (!(PSW & PSW_Z)) State.regs[REG_PC] += SEXT8 (insn & 0xff) - 2; } /* bgt label:8 */ void OP_C100 (insn, extension) unsigned long insn, extension; { /* The dispatching code will add 2 after we return, so we subtract two here to make things right. */ if (!((PSW & PSW_Z) || (((PSW & PSW_N) != 0) ^ ((PSW & PSW_V) != 0)))) State.regs[REG_PC] += SEXT8 (insn & 0xff) - 2; } /* bge label:8 */ void OP_C200 (insn, extension) unsigned long insn, extension; { /* The dispatching code will add 2 after we return, so we subtract two here to make things right. */ if (!(((PSW & PSW_N) != 0) ^ ((PSW & PSW_V) != 0))) State.regs[REG_PC] += SEXT8 (insn & 0xff) - 2; } /* ble label:8 */ void OP_C300 (insn, extension) unsigned long insn, extension; { /* The dispatching code will add 2 after we return, so we subtract two here to make things right. */ if ((PSW & PSW_Z) || (((PSW & PSW_N) != 0) ^ ((PSW & PSW_V) != 0))) State.regs[REG_PC] += SEXT8 (insn & 0xff) - 2; } /* blt label:8 */ void OP_C000 (insn, extension) unsigned long insn, extension; { /* The dispatching code will add 2 after we return, so we subtract two here to make things right. */ if (((PSW & PSW_N) != 0) ^ ((PSW & PSW_V) != 0)) State.regs[REG_PC] += SEXT8 (insn & 0xff) - 2; } /* bhi label:8 */ void OP_C500 (insn, extension) unsigned long insn, extension; { /* The dispatching code will add 2 after we return, so we subtract two here to make things right. */ if (!(((PSW & PSW_C) != 0) || (PSW & PSW_Z) != 0)) State.regs[REG_PC] += SEXT8 (insn & 0xff) - 2; } /* bcc label:8 */ void OP_C600 (insn, extension) unsigned long insn, extension; { /* The dispatching code will add 2 after we return, so we subtract two here to make things right. */ if (!(PSW & PSW_C)) State.regs[REG_PC] += SEXT8 (insn & 0xff) - 2; } /* bls label:8 */ void OP_C700 (insn, extension) unsigned long insn, extension; { /* The dispatching code will add 2 after we return, so we subtract two here to make things right. */ if (((PSW & PSW_C) != 0) || (PSW & PSW_Z) != 0) State.regs[REG_PC] += SEXT8 (insn & 0xff) - 2; } /* bcs label:8 */ void OP_C400 (insn, extension) unsigned long insn, extension; { /* The dispatching code will add 2 after we return, so we subtract two here to make things right. */ if (PSW & PSW_C) State.regs[REG_PC] += SEXT8 (insn & 0xff) - 2; } /* bvc label:8 */ void OP_F8E800 (insn, extension) unsigned long insn, extension; { /* The dispatching code will add 3 after we return, so we subtract two here to make things right. */ if (!(PSW & PSW_V)) State.regs[REG_PC] += SEXT8 (insn & 0xff) - 3; } /* bvs label:8 */ void OP_F8E900 (insn, extension) unsigned long insn, extension; { /* The dispatching code will add 3 after we return, so we subtract two here to make things right. */ if (PSW & PSW_V) State.regs[REG_PC] += SEXT8 (insn & 0xff) - 3; } /* bnc label:8 */ void OP_F8EA00 (insn, extension) unsigned long insn, extension; { /* The dispatching code will add 3 after we return, so we subtract two here to make things right. */ if (!(PSW & PSW_N)) State.regs[REG_PC] += SEXT8 (insn & 0xff) - 3; } /* bns label:8 */ void OP_F8EB00 (insn, extension) unsigned long insn, extension; { /* The dispatching code will add 3 after we return, so we subtract two here to make things right. */ if (PSW & PSW_N) State.regs[REG_PC] += SEXT8 (insn & 0xff) - 3; } /* bra label:8 */ void OP_CA00 (insn, extension) unsigned long insn, extension; { /* The dispatching code will add 2 after we return, so we subtract two here to make things right. */ State.regs[REG_PC] += SEXT8 (insn & 0xff) - 2; } /* leq */ void OP_D8 (insn, extension) unsigned long insn, extension; { /* The dispatching code will add 1 after we return, so we subtract one here to make things right. */ if (PSW & PSW_Z) State.regs[REG_PC] = State.regs[REG_LAR] - 4 - 1; } /* lne */ void OP_D9 (insn, extension) unsigned long insn, extension; { /* The dispatching code will add 1 after we return, so we subtract one here to make things right. */ if (!(PSW & PSW_Z)) State.regs[REG_PC] = State.regs[REG_LAR] - 4 - 1; } /* lgt */ void OP_D1 (insn, extension) unsigned long insn, extension; { /* The dispatching code will add 1 after we return, so we subtract one here to make things right. */ if (!((PSW & PSW_Z) || (((PSW & PSW_N) != 0) ^ ((PSW & PSW_V) != 0)))) State.regs[REG_PC] = State.regs[REG_LAR] - 4 - 1; } /* lge */ void OP_D2 (insn, extension) unsigned long insn, extension; { /* The dispatching code will add 1 after we return, so we subtract one here to make things right. */ if (!(((PSW & PSW_N) != 0) ^ ((PSW & PSW_V) != 0))) State.regs[REG_PC] = State.regs[REG_LAR] - 4 - 1; } /* lle */ void OP_D3 (insn, extension) unsigned long insn, extension; { /* The dispatching code will add 1 after we return, so we subtract one here to make things right. */ if ((PSW & PSW_Z) || (((PSW & PSW_N) != 0) ^ ((PSW & PSW_V) != 0))) State.regs[REG_PC] = State.regs[REG_LAR] - 4 - 1; } /* llt */ void OP_D0 (insn, extension) unsigned long insn, extension; { /* The dispatching code will add 1 after we return, so we subtract one here to make things right. */ if (((PSW & PSW_N) != 0) ^ ((PSW & PSW_V) != 0)) State.regs[REG_PC] = State.regs[REG_LAR] - 4 - 1; } /* lhi */ void OP_D5 (insn, extension) unsigned long insn, extension; { /* The dispatching code will add 1 after we return, so we subtract one here to make things right. */ if (!(((PSW & PSW_C) != 0) || (PSW & PSW_Z) != 0)) State.regs[REG_PC] = State.regs[REG_LAR] - 4 - 1; } /* lcc */ void OP_D6 (insn, extension) unsigned long insn, extension; { /* The dispatching code will add 1 after we return, so we subtract one here to make things right. */ if (!(PSW & PSW_C)) State.regs[REG_PC] = State.regs[REG_LAR] - 4 - 1; } /* lls */ void OP_D7 (insn, extension) unsigned long insn, extension; { /* The dispatching code will add 1 after we return, so we subtract one here to make things right. */ if (((PSW & PSW_C) != 0) || (PSW & PSW_Z) != 0) State.regs[REG_PC] = State.regs[REG_LAR] - 4 - 1; } /* lcs */ void OP_D4 (insn, extension) unsigned long insn, extension; { /* The dispatching code will add 1 after we return, so we subtract one here to make things right. */ if (PSW & PSW_C) State.regs[REG_PC] = State.regs[REG_LAR] - 4 - 1; } /* lra */ void OP_DA (insn, extension) unsigned long insn, extension; { State.regs[REG_PC] = State.regs[REG_LAR] - 4 - 1; } /* setlb */ void OP_DB (insn, extension) unsigned long insn, extension; { State.regs[REG_LIR] = load_mem_big (State.regs[REG_PC] + 1, 4); State.regs[REG_LAR] = State.regs[REG_PC] + 5; } /* jmp (an) */ void OP_F0F4 (insn, extension) unsigned long insn, extension; { State.regs[REG_PC] = State.regs[REG_A0 + REG0 (insn)] - 2; } /* jmp label:16 */ void OP_CC0000 (insn, extension) unsigned long insn, extension; { State.regs[REG_PC] += SEXT16 (insn & 0xffff) - 3; } /* jmp label:32 */ void OP_DC000000 (insn, extension) unsigned long insn, extension; { State.regs[REG_PC] += (((insn & 0xffffff) << 8) + extension) - 5; } /* call label:16,reg_list,imm8 */ void OP_CD000000 (insn, extension) unsigned long insn, extension; { unsigned int next_pc, sp, adjust; unsigned long mask; sp = State.regs[REG_SP]; next_pc = State.regs[REG_PC] + 2; State.mem[sp] = next_pc & 0xff; State.mem[sp+1] = (next_pc & 0xff00) >> 8; State.mem[sp+2] = (next_pc & 0xff0000) >> 16; State.mem[sp+3] = (next_pc & 0xff000000) >> 24; mask = insn & 0xff; adjust = 0; if (mask & 0x80) { adjust -= 4; State.regs[REG_D0 + 2] = load_mem (sp + adjust, 4); } if (mask & 0x40) { adjust -= 4; State.regs[REG_D0 + 3] = load_mem (sp + adjust, 4); } if (mask & 0x20) { adjust -= 4; State.regs[REG_A0 + 2] = load_mem (sp + adjust, 4); } if (mask & 0x10) { adjust -= 4; State.regs[REG_A0 + 3] = load_mem (sp + adjust, 4); } if (mask & 0x8) { adjust -= 4; State.regs[REG_D0] = load_mem (sp + adjust, 4); adjust -= 4; State.regs[REG_D0 + 1] = load_mem (sp + adjust, 4); adjust -= 4; State.regs[REG_A0] = load_mem (sp + adjust, 4); adjust -= 4; State.regs[REG_A0 + 1] = load_mem (sp + adjust, 4); adjust -= 4; State.regs[REG_MDR] = load_mem (sp + adjust, 4); adjust -= 4; State.regs[REG_LIR] = load_mem (sp + adjust, 4); adjust -= 4; State.regs[REG_LAR] = load_mem (sp + adjust, 4); adjust -= 4; } /* And make sure to update the stack pointer. */ State.regs[REG_SP] -= extension; State.regs[REG_MDR] = next_pc; State.regs[REG_PC] += SEXT16 ((insn & 0xffff00) >> 8) - 5; } /* call label:32,reg_list,imm8*/ void OP_DD000000 (insn, extension) unsigned long insn, extension; { unsigned int next_pc, sp, adjust; unsigned long mask; sp = State.regs[REG_SP]; next_pc = State.regs[REG_PC] + 2; State.mem[sp] = next_pc & 0xff; State.mem[sp+1] = (next_pc & 0xff00) >> 8; State.mem[sp+2] = (next_pc & 0xff0000) >> 16; State.mem[sp+3] = (next_pc & 0xff000000) >> 24; mask = (extension & 0xff00) >> 8; adjust = 0; if (mask & 0x80) { adjust -= 4; State.regs[REG_D0 + 2] = load_mem (sp + adjust, 4); } if (mask & 0x40) { adjust -= 4; State.regs[REG_D0 + 3] = load_mem (sp + adjust, 4); } if (mask & 0x20) { adjust -= 4; State.regs[REG_A0 + 2] = load_mem (sp + adjust, 4); } if (mask & 0x10) { adjust -= 4; State.regs[REG_A0 + 3] = load_mem (sp + adjust, 4); } if (mask & 0x8) { adjust -= 4; State.regs[REG_D0] = load_mem (sp + adjust, 4); adjust -= 4; State.regs[REG_D0 + 1] = load_mem (sp + adjust, 4); adjust -= 4; State.regs[REG_A0] = load_mem (sp + adjust, 4); adjust -= 4; State.regs[REG_A0 + 1] = load_mem (sp + adjust, 4); adjust -= 4; State.regs[REG_MDR] = load_mem (sp + adjust, 4); adjust -= 4; State.regs[REG_LIR] = load_mem (sp + adjust, 4); adjust -= 4; State.regs[REG_LAR] = load_mem (sp + adjust, 4); adjust -= 4; } /* And make sure to update the stack pointer. */ State.regs[REG_SP] -= (extension & 0xff); State.regs[REG_MDR] = next_pc; State.regs[REG_PC] += (((insn & 0xffffff) << 8) | ((extension & 0xff0000) >> 16)) - 7; } /* calls (an) */ void OP_F0F0 (insn, extension) unsigned long insn, extension; { unsigned int next_pc, sp; sp = State.regs[REG_SP]; next_pc = State.regs[REG_PC] + 2; State.mem[sp] = next_pc & 0xff; State.mem[sp+1] = (next_pc & 0xff00) >> 8; State.mem[sp+2] = (next_pc & 0xff0000) >> 16; State.mem[sp+3] = (next_pc & 0xff000000) >> 24; State.regs[REG_MDR] = next_pc; State.regs[REG_PC] = State.regs[REG_A0 + REG0 (insn)] - 2; } /* calls label:16 */ void OP_FAFF0000 (insn, extension) unsigned long insn, extension; { unsigned int next_pc, sp; sp = State.regs[REG_SP]; next_pc = State.regs[REG_PC] + 4; State.mem[sp] = next_pc & 0xff; State.mem[sp+1] = (next_pc & 0xff00) >> 8; State.mem[sp+2] = (next_pc & 0xff0000) >> 16; State.mem[sp+3] = (next_pc & 0xff000000) >> 24; State.regs[REG_MDR] = next_pc; State.regs[REG_PC] += SEXT16 (insn & 0xffff) - 4; } /* calls label:32 */ void OP_FCFF0000 (insn, extension) unsigned long insn, extension; { unsigned int next_pc, sp; sp = State.regs[REG_SP]; next_pc = State.regs[REG_PC] + 6; State.mem[sp] = next_pc & 0xff; State.mem[sp+1] = (next_pc & 0xff00) >> 8; State.mem[sp+2] = (next_pc & 0xff0000) >> 16; State.mem[sp+3] = (next_pc & 0xff000000) >> 24; State.regs[REG_MDR] = next_pc; State.regs[REG_PC] += (((insn & 0xffff) << 16) + extension) - 6; } /* ret reg_list, imm8 */ void OP_DF0000 (insn, extension) unsigned long insn, extension; { unsigned int sp; unsigned long mask; State.regs[REG_SP] += insn & 0xff; sp = State.regs[REG_SP]; mask = (insn & 0xff00) >> 8; if (mask & 0x8) { sp += 4; State.regs[REG_LAR] = load_mem (sp, 4); sp += 4; State.regs[REG_LIR] = load_mem (sp, 4); sp += 4; State.regs[REG_MDR] = load_mem (sp, 4); sp += 4; State.regs[REG_A0 + 1] = load_mem (sp, 4); sp += 4; State.regs[REG_A0] = load_mem (sp, 4); sp += 4; State.regs[REG_D0 + 1] = load_mem (sp, 4); sp += 4; State.regs[REG_D0] = load_mem (sp, 4); sp += 4; } if (mask & 0x10) { State.regs[REG_A0 + 3] = load_mem (sp, 4); sp += 4; } if (mask & 0x20) { State.regs[REG_A0 + 2] = load_mem (sp, 4); sp += 4; } if (mask & 0x40) { State.regs[REG_D0 + 3] = load_mem (sp, 4); sp += 4; } if (mask & 0x80) { State.regs[REG_D0 + 2] = load_mem (sp, 4); sp += 4; } /* And make sure to update the stack pointer. */ State.regs[REG_SP] = sp; /* Restore the PC value. */ State.regs[REG_PC] = (State.mem[sp] | (State.mem[sp+1] << 8) | (State.mem[sp+2] << 16) | (State.mem[sp+3] << 24)); State.regs[REG_PC] -= 3; } /* retf reg_list,imm8 */ void OP_DE0000 (insn, extension) unsigned long insn, extension; { unsigned int sp; unsigned long mask; sp = State.regs[REG_SP] + (insn & 0xff); State.regs[REG_SP] = sp; State.regs[REG_PC] = State.regs[REG_MDR] - 3; sp = State.regs[REG_SP]; mask = (insn & 0xff00) >> 8; if (mask & 0x8) { sp += 4; State.regs[REG_LAR] = load_mem (sp, 4); sp += 4; State.regs[REG_LIR] = load_mem (sp, 4); sp += 4; State.regs[REG_MDR] = load_mem (sp, 4); sp += 4; State.regs[REG_A0 + 1] = load_mem (sp, 4); sp += 4; State.regs[REG_A0] = load_mem (sp, 4); sp += 4; State.regs[REG_D0 + 1] = load_mem (sp, 4); sp += 4; State.regs[REG_D0] = load_mem (sp, 4); sp += 4; } if (mask & 0x10) { State.regs[REG_A0 + 3] = load_mem (sp, 4); sp += 4; } if (mask & 0x20) { State.regs[REG_A0 + 2] = load_mem (sp, 4); sp += 4; } if (mask & 0x40) { State.regs[REG_D0 + 3] = load_mem (sp, 4); sp += 4; } if (mask & 0x80) { State.regs[REG_D0 + 2] = load_mem (sp, 4); sp += 4; } /* And make sure to update the stack pointer. */ State.regs[REG_SP] = sp; } /* rets */ void OP_F0FC (insn, extension) unsigned long insn, extension; { unsigned int sp; sp = State.regs[REG_SP]; State.regs[REG_PC] = (State.mem[sp] | (State.mem[sp+1] << 8) | (State.mem[sp+2] << 16) | (State.mem[sp+3] << 24)); State.regs[REG_PC] -= 2; } /* rti */ void OP_F0FD (insn, extension) unsigned long insn, extension; { unsigned int sp, next_pc; PSW = State.mem[sp] | (State.mem[sp + 1] << 8); State.regs[REG_PC] = (State.mem[sp+4] | (State.mem[sp+5] << 8) | (State.mem[sp+6] << 16) | (State.mem[sp+7] << 24)); State.regs[REG_SP] += 8; } /* trap */ void OP_F0FE (insn, extension) unsigned long insn, extension; { unsigned int sp, next_pc; sp = State.regs[REG_SP]; next_pc = State.regs[REG_PC] + 2; State.mem[sp] = next_pc & 0xff; State.mem[sp+1] = (next_pc & 0xff00) >> 8; State.mem[sp+2] = (next_pc & 0xff0000) >> 16; State.mem[sp+3] = (next_pc & 0xff000000) >> 24; State.regs[REG_PC] = 0x40000010 - 2; abort (); } /* syscall */ void OP_F020 (insn, extension) unsigned long insn, extension; { /* We use this for simulated system calls; we may need to change it to a reserved instruction if we conflict with uses at Matsushita. */ int save_errno = errno; errno = 0; /* Registers passed to trap 0 */ /* Function number. */ #define FUNC (State.regs[0]) /* Parameters. */ #define PARM1 (State.regs[1]) #define PARM2 (load_mem (State.regs[REG_SP] + 12, 4)) #define PARM3 (load_mem (State.regs[REG_SP] + 16, 4)) /* Registers set by trap 0 */ #define RETVAL State.regs[0] /* return value */ #define RETERR State.regs[1] /* return error code */ /* Turn a pointer in a register into a pointer into real memory. */ #define MEMPTR(x) (State.mem + x) switch (FUNC) { #if !defined(__GO32__) && !defined(_WIN32) case SYS_fork: RETVAL = fork (); break; case SYS_execve: RETVAL = execve (MEMPTR (PARM1), (char **) MEMPTR (PARM2), (char **)MEMPTR (PARM3)); break; #ifdef SYS_execv case SYS_execv: RETVAL = execve (MEMPTR (PARM1), (char **) MEMPTR (PARM2), NULL); break; #endif #endif case SYS_read: RETVAL = mn10300_callback->read (mn10300_callback, PARM1, MEMPTR (PARM2), PARM3); break; case SYS_write: if (PARM1 == 1) RETVAL = (int)mn10300_callback->write_stdout (mn10300_callback, MEMPTR (PARM2), PARM3); else RETVAL = (int)mn10300_callback->write (mn10300_callback, PARM1, MEMPTR (PARM2), PARM3); break; case SYS_lseek: RETVAL = mn10300_callback->lseek (mn10300_callback, PARM1, PARM2, PARM3); break; case SYS_close: RETVAL = mn10300_callback->close (mn10300_callback, PARM1); break; case SYS_open: RETVAL = mn10300_callback->open (mn10300_callback, MEMPTR (PARM1), PARM2); break; case SYS_exit: /* EXIT - caller can look in PARM1 to work out the reason */ if (PARM1 == 0xdead || PARM1 == 0x1) State.exception = SIGABRT; else State.exception = SIGQUIT; break; case SYS_stat: /* added at hmsi */ /* stat system call */ { struct stat host_stat; reg_t buf; RETVAL = stat (MEMPTR (PARM1), &host_stat); buf = PARM2; /* Just wild-assed guesses. */ store_mem (buf, 2, host_stat.st_dev); store_mem (buf + 2, 2, host_stat.st_ino); store_mem (buf + 4, 4, host_stat.st_mode); store_mem (buf + 8, 2, host_stat.st_nlink); store_mem (buf + 10, 2, host_stat.st_uid); store_mem (buf + 12, 2, host_stat.st_gid); store_mem (buf + 14, 2, host_stat.st_rdev); store_mem (buf + 16, 4, host_stat.st_size); store_mem (buf + 20, 4, host_stat.st_atime); store_mem (buf + 28, 4, host_stat.st_mtime); store_mem (buf + 36, 4, host_stat.st_ctime); } break; case SYS_chown: RETVAL = chown (MEMPTR (PARM1), PARM2, PARM3); break; case SYS_chmod: RETVAL = chmod (MEMPTR (PARM1), PARM2); break; #ifdef SYS_time case SYS_time: RETVAL = time ((void*) MEMPTR (PARM1)); break; #endif #ifdef SYS_times case SYS_times: { struct tms tms; RETVAL = times (&tms); store_mem (PARM1, 4, tms.tms_utime); store_mem (PARM1 + 4, 4, tms.tms_stime); store_mem (PARM1 + 8, 4, tms.tms_cutime); store_mem (PARM1 + 12, 4, tms.tms_cstime); break; } #endif case SYS_gettimeofday: { struct timeval t; struct timezone tz; RETVAL = gettimeofday (&t, &tz); store_mem (PARM1, 4, t.tv_sec); store_mem (PARM1 + 4, 4, t.tv_usec); store_mem (PARM2, 4, tz.tz_minuteswest); store_mem (PARM2 + 4, 4, tz.tz_dsttime); break; } #ifdef SYS_utime case SYS_utime: /* Cast the second argument to void *, to avoid type mismatch if a prototype is present. */ RETVAL = utime (MEMPTR (PARM1), (void *) MEMPTR (PARM2)); break; #endif default: abort (); } RETERR = errno; errno = save_errno; } /* rtm */ void OP_F0FF (insn, extension) unsigned long insn, extension; { abort (); } /* nop */ void OP_CB (insn, extension) unsigned long insn, extension; { } /* putx */ void OP_F500 (insn, extension) unsigned long insn, extension; { abort (); } /* getx */ void OP_F6F0 (insn, extension) unsigned long insn, extension; { abort (); } /* mulq */ void OP_F600 (insn, extension) unsigned long insn, extension; { abort (); } /* mulq */ void OP_F90000 (insn, extension) unsigned long insn, extension; { abort (); } /* mulq */ void OP_FB000000 (insn, extension) unsigned long insn, extension; { abort (); } /* mulq */ void OP_FD000000 (insn, extension) unsigned long insn, extension; { abort (); } /* mulqu */ void OP_F610 (insn, extension) unsigned long insn, extension; { abort (); } /* mulqu */ void OP_F91400 (insn, extension) unsigned long insn, extension; { abort (); } /* mulqu */ void OP_FB140000 (insn, extension) unsigned long insn, extension; { abort (); } /* mulqu */ void OP_FD140000 (insn, extension) unsigned long insn, extension; { abort (); } /* sat16 */ void OP_F640 (insn, extension) unsigned long insn, extension; { abort (); } /* sat24 */ void OP_F650 (insn, extension) unsigned long insn, extension; { abort (); } /* bsch */ void OP_F670 (insn, extension) unsigned long insn, extension; { abort (); } /* breakpoint */ void OP_FF (insn, extension) unsigned long insn, extension; { State.exception = SIGTRAP; PC -= 1; }