diff --git a/c/Makefile b/c/Makefile index 09abbcb..75e4a32 100644 --- a/c/Makefile +++ b/c/Makefile @@ -34,3 +34,14 @@ main: $(OBJS) $(CC) $^ -o $@ -include $(shell find -type f -name '*.d') + +.SUFFIXES: +.INTERMEDIATE: +.SECONDARY: +.PHONY: all clean + +%: RCS/%,v +%: RCS/% +%: %,v +%: s.% +%: SCCS/s.% diff --git a/c/decode_execute.c b/c/decode_execute.c index 3fc969f..69fdcba 100644 --- a/c/decode_execute.c +++ b/c/decode_execute.c @@ -456,94 +456,120 @@ enum decode_status decode_and_execute_instruction(struct architectural_state * s } case 0b1111000000000000: // FADD FRm,FRn { - uint32_t m = (code >> 4) & ((1 << 4) - 1); - uint32_t n = (code >> 8) & ((1 << 4) - 1); - fadd__source_and_destination_operands(state, map, m, n); - return DECODE__DEFINED; + if (state->fpscr.bits.pr == 0) { + uint32_t m = (code >> 4) & ((1 << 4) - 1); + uint32_t n = (code >> 8) & ((1 << 4) - 1); + fadd__source_and_destination_operands(state, map, m, n); + return DECODE__DEFINED; + } else break; } case 0b1111000000000001: // FSUB FRm,FRn { - uint32_t m = (code >> 4) & ((1 << 4) - 1); - uint32_t n = (code >> 8) & ((1 << 4) - 1); - fsub__source_and_destination_operands(state, map, m, n); - return DECODE__DEFINED; + if (state->fpscr.bits.pr == 0) { + uint32_t m = (code >> 4) & ((1 << 4) - 1); + uint32_t n = (code >> 8) & ((1 << 4) - 1); + fsub__source_and_destination_operands(state, map, m, n); + return DECODE__DEFINED; + } else break; } case 0b1111000000000010: // FMUL FRm,FRn { - uint32_t m = (code >> 4) & ((1 << 4) - 1); - uint32_t n = (code >> 8) & ((1 << 4) - 1); - fmul__source_and_destination_operands(state, map, m, n); - return DECODE__DEFINED; + if (state->fpscr.bits.pr == 0) { + uint32_t m = (code >> 4) & ((1 << 4) - 1); + uint32_t n = (code >> 8) & ((1 << 4) - 1); + fmul__source_and_destination_operands(state, map, m, n); + return DECODE__DEFINED; + } else break; } case 0b1111000000000011: // FDIV FRm,FRn { - uint32_t m = (code >> 4) & ((1 << 4) - 1); - uint32_t n = (code >> 8) & ((1 << 4) - 1); - fdiv__source_and_destination_operands(state, map, m, n); - return DECODE__DEFINED; + if (state->fpscr.bits.pr == 0) { + uint32_t m = (code >> 4) & ((1 << 4) - 1); + uint32_t n = (code >> 8) & ((1 << 4) - 1); + fdiv__source_and_destination_operands(state, map, m, n); + return DECODE__DEFINED; + } else break; } case 0b1111000000000100: // FCMP/EQ FRm,FRn { - uint32_t m = (code >> 4) & ((1 << 4) - 1); - uint32_t n = (code >> 8) & ((1 << 4) - 1); - fcmp_eq__source_and_destination_operands(state, map, m, n); - return DECODE__DEFINED; + if (state->fpscr.bits.pr == 0) { + uint32_t m = (code >> 4) & ((1 << 4) - 1); + uint32_t n = (code >> 8) & ((1 << 4) - 1); + fcmp_eq__source_and_destination_operands(state, map, m, n); + return DECODE__DEFINED; + } else break; } case 0b1111000000000101: // FCMP/GT FRm,FRn { - uint32_t m = (code >> 4) & ((1 << 4) - 1); - uint32_t n = (code >> 8) & ((1 << 4) - 1); - fcmp_gt__source_and_destination_operands(state, map, m, n); - return DECODE__DEFINED; + if (state->fpscr.bits.pr == 0) { + uint32_t m = (code >> 4) & ((1 << 4) - 1); + uint32_t n = (code >> 8) & ((1 << 4) - 1); + fcmp_gt__source_and_destination_operands(state, map, m, n); + return DECODE__DEFINED; + } else break; } case 0b1111000000000110: // FMOV.S @(R0,Rm),FRn { - uint32_t m = (code >> 4) & ((1 << 4) - 1); - uint32_t n = (code >> 8) & ((1 << 4) - 1); - fmov_s__load_indexed_register_indirect(state, map, m, n); - return DECODE__DEFINED; + if (state->fpscr.bits.sz == 0) { + uint32_t m = (code >> 4) & ((1 << 4) - 1); + uint32_t n = (code >> 8) & ((1 << 4) - 1); + fmov_s__load_indexed_register_indirect(state, map, m, n); + return DECODE__DEFINED; + } else break; } case 0b1111000000000111: // FMOV.S FRm,@(R0,Rn) { - uint32_t m = (code >> 4) & ((1 << 4) - 1); - uint32_t n = (code >> 8) & ((1 << 4) - 1); - fmov_s__store_indexed_register_indirect(state, map, m, n); - return DECODE__DEFINED; + if (state->fpscr.bits.sz == 0) { + uint32_t m = (code >> 4) & ((1 << 4) - 1); + uint32_t n = (code >> 8) & ((1 << 4) - 1); + fmov_s__store_indexed_register_indirect(state, map, m, n); + return DECODE__DEFINED; + } else break; } case 0b1111000000001000: // FMOV.S @Rm,FRn { - uint32_t m = (code >> 4) & ((1 << 4) - 1); - uint32_t n = (code >> 8) & ((1 << 4) - 1); - fmov_s__load_register_direct_data_transfer(state, map, m, n); - return DECODE__DEFINED; + if (state->fpscr.bits.sz == 0) { + uint32_t m = (code >> 4) & ((1 << 4) - 1); + uint32_t n = (code >> 8) & ((1 << 4) - 1); + fmov_s__load_register_direct_data_transfer(state, map, m, n); + return DECODE__DEFINED; + } else break; } case 0b1111000000001001: // FMOV.S @Rm+,FRn { - uint32_t m = (code >> 4) & ((1 << 4) - 1); - uint32_t n = (code >> 8) & ((1 << 4) - 1); - fmov_s__load_direct_data_transfer_from_register(state, map, m, n); - return DECODE__DEFINED; + if (state->fpscr.bits.sz == 0) { + uint32_t m = (code >> 4) & ((1 << 4) - 1); + uint32_t n = (code >> 8) & ((1 << 4) - 1); + fmov_s__load_direct_data_transfer_from_register(state, map, m, n); + return DECODE__DEFINED; + } else break; } case 0b1111000000001010: // FMOV.S FRm,@Rn { - uint32_t m = (code >> 4) & ((1 << 4) - 1); - uint32_t n = (code >> 8) & ((1 << 4) - 1); - fmov_s__store_register_direct_data_transfer(state, map, m, n); - return DECODE__DEFINED; + if (state->fpscr.bits.sz == 0) { + uint32_t m = (code >> 4) & ((1 << 4) - 1); + uint32_t n = (code >> 8) & ((1 << 4) - 1); + fmov_s__store_register_direct_data_transfer(state, map, m, n); + return DECODE__DEFINED; + } else break; } case 0b1111000000001011: // FMOV.S FRm,@-Rn { - uint32_t m = (code >> 4) & ((1 << 4) - 1); - uint32_t n = (code >> 8) & ((1 << 4) - 1); - fmov_s__store_direct_data_transfer_from_register(state, map, m, n); - return DECODE__DEFINED; + if (state->fpscr.bits.sz == 0) { + uint32_t m = (code >> 4) & ((1 << 4) - 1); + uint32_t n = (code >> 8) & ((1 << 4) - 1); + fmov_s__store_direct_data_transfer_from_register(state, map, m, n); + return DECODE__DEFINED; + } else break; } case 0b1111000000001100: // FMOV FRm,FRn { - uint32_t m = (code >> 4) & ((1 << 4) - 1); - uint32_t n = (code >> 8) & ((1 << 4) - 1); - fmov__source_and_destination_operands(state, map, m, n); - return DECODE__DEFINED; + if (state->fpscr.bits.sz == 0) { + uint32_t m = (code >> 4) & ((1 << 4) - 1); + uint32_t n = (code >> 8) & ((1 << 4) - 1); + fmov__source_and_destination_operands(state, map, m, n); + return DECODE__DEFINED; + } else break; } case 0b1111000000001110: // FMAC FR0,FRm,FRn { @@ -1138,33 +1164,43 @@ enum decode_status decode_and_execute_instruction(struct architectural_state * s } case 0b1111000000101101: // FLOAT FPUL,FRn { - uint32_t n = (code >> 8) & ((1 << 4) - 1); - float__fpul_to_frn(state, map, n); - return DECODE__DEFINED; + if (state->fpscr.bits.pr == 0) { + uint32_t n = (code >> 8) & ((1 << 4) - 1); + float__fpul_to_frn(state, map, n); + return DECODE__DEFINED; + } else break; } case 0b1111000000111101: // FTRC FRm,FPUL { - uint32_t m = (code >> 8) & ((1 << 4) - 1); - ftrc__frm_to_fpul(state, map, m); - return DECODE__DEFINED; + if (state->fpscr.bits.pr == 0) { + uint32_t m = (code >> 8) & ((1 << 4) - 1); + ftrc__frm_to_fpul(state, map, m); + return DECODE__DEFINED; + } else break; } case 0b1111000001001101: // FNEG FRn { - uint32_t n = (code >> 8) & ((1 << 4) - 1); - fneg__destination_operand_only(state, map, n); - return DECODE__DEFINED; + if (state->fpscr.bits.pr == 0) { + uint32_t n = (code >> 8) & ((1 << 4) - 1); + fneg__destination_operand_only(state, map, n); + return DECODE__DEFINED; + } else break; } case 0b1111000001011101: // FABS FRn { - uint32_t n = (code >> 8) & ((1 << 4) - 1); - fabs__destination_operand_only(state, map, n); - return DECODE__DEFINED; + if (state->fpscr.bits.pr == 0) { + uint32_t n = (code >> 8) & ((1 << 4) - 1); + fabs__destination_operand_only(state, map, n); + return DECODE__DEFINED; + } else break; } case 0b1111000001101101: // FSQRT FRn { - uint32_t n = (code >> 8) & ((1 << 4) - 1); - fsqrt__destination_operand_only(state, map, n); - return DECODE__DEFINED; + if (state->fpscr.bits.pr == 0) { + uint32_t n = (code >> 8) & ((1 << 4) - 1); + fsqrt__destination_operand_only(state, map, n); + return DECODE__DEFINED; + } else break; } case 0b1111000010001101: // FLDI0 FRn { @@ -1274,193 +1310,247 @@ enum decode_status decode_and_execute_instruction(struct architectural_state * s switch (code & 0b1111000100011111) { case 0b1111000000000000: // FADD DRm,DRn { - uint32_t m = (code >> 5) & ((1 << 3) - 1); - uint32_t n = (code >> 9) & ((1 << 3) - 1); - fadd__source_and_destination_operands_double(state, map, m, n); - return DECODE__DEFINED; + if (state->fpscr.bits.pr == 1) { + uint32_t m = (code >> 5) & ((1 << 3) - 1); + uint32_t n = (code >> 9) & ((1 << 3) - 1); + fadd__source_and_destination_operands_double(state, map, m, n); + return DECODE__DEFINED; + } else break; } case 0b1111000000000001: // FSUB DRm,DRn { - uint32_t m = (code >> 5) & ((1 << 3) - 1); - uint32_t n = (code >> 9) & ((1 << 3) - 1); - fsub__source_and_destination_operands_double(state, map, m, n); - return DECODE__DEFINED; + if (state->fpscr.bits.pr == 1) { + uint32_t m = (code >> 5) & ((1 << 3) - 1); + uint32_t n = (code >> 9) & ((1 << 3) - 1); + fsub__source_and_destination_operands_double(state, map, m, n); + return DECODE__DEFINED; + } else break; } case 0b1111000000000010: // FMUL DRm,DRn { - uint32_t m = (code >> 5) & ((1 << 3) - 1); - uint32_t n = (code >> 9) & ((1 << 3) - 1); - fmul__source_and_destination_operands_double(state, map, m, n); - return DECODE__DEFINED; + if (state->fpscr.bits.pr == 1) { + uint32_t m = (code >> 5) & ((1 << 3) - 1); + uint32_t n = (code >> 9) & ((1 << 3) - 1); + fmul__source_and_destination_operands_double(state, map, m, n); + return DECODE__DEFINED; + } else break; } case 0b1111000000000011: // FDIV DRm,DRn { - uint32_t m = (code >> 5) & ((1 << 3) - 1); - uint32_t n = (code >> 9) & ((1 << 3) - 1); - fdiv__source_and_destination_operands_double(state, map, m, n); - return DECODE__DEFINED; + if (state->fpscr.bits.pr == 1) { + uint32_t m = (code >> 5) & ((1 << 3) - 1); + uint32_t n = (code >> 9) & ((1 << 3) - 1); + fdiv__source_and_destination_operands_double(state, map, m, n); + return DECODE__DEFINED; + } else break; } case 0b1111000000000100: // FCMP/EQ DRm,DRn { - uint32_t m = (code >> 5) & ((1 << 3) - 1); - uint32_t n = (code >> 9) & ((1 << 3) - 1); - fcmp_eq__source_and_destination_operands_double(state, map, m, n); - return DECODE__DEFINED; + if (state->fpscr.bits.pr == 1) { + uint32_t m = (code >> 5) & ((1 << 3) - 1); + uint32_t n = (code >> 9) & ((1 << 3) - 1); + fcmp_eq__source_and_destination_operands_double(state, map, m, n); + return DECODE__DEFINED; + } else break; } case 0b1111000000000101: // FCMP/GT DRm,DRn { - uint32_t m = (code >> 5) & ((1 << 3) - 1); - uint32_t n = (code >> 9) & ((1 << 3) - 1); - fcmp_gt__source_and_destination_operands_double(state, map, m, n); - return DECODE__DEFINED; + if (state->fpscr.bits.pr == 1) { + uint32_t m = (code >> 5) & ((1 << 3) - 1); + uint32_t n = (code >> 9) & ((1 << 3) - 1); + fcmp_gt__source_and_destination_operands_double(state, map, m, n); + return DECODE__DEFINED; + } else break; } case 0b1111000000001100: // FMOV DRm,DRn { - uint32_t m = (code >> 5) & ((1 << 3) - 1); - uint32_t n = (code >> 9) & ((1 << 3) - 1); - fmov__source_and_destination_operands_double(state, map, m, n); - return DECODE__DEFINED; + if (state->fpscr.bits.sz == 1) { + uint32_t m = (code >> 5) & ((1 << 3) - 1); + uint32_t n = (code >> 9) & ((1 << 3) - 1); + fmov__source_and_destination_operands_double(state, map, m, n); + return DECODE__DEFINED; + } else break; } case 0b1111000000011100: // FMOV XDm,DRn { - uint32_t m = (code >> 5) & ((1 << 3) - 1); - uint32_t n = (code >> 9) & ((1 << 3) - 1); - fmov__bank_to_double(state, map, m, n); - return DECODE__DEFINED; + if (state->fpscr.bits.sz == 1) { + uint32_t m = (code >> 5) & ((1 << 3) - 1); + uint32_t n = (code >> 9) & ((1 << 3) - 1); + fmov__bank_to_double(state, map, m, n); + return DECODE__DEFINED; + } else break; } case 0b1111000100001100: // FMOV DRm,XDn { - uint32_t m = (code >> 5) & ((1 << 3) - 1); - uint32_t n = (code >> 9) & ((1 << 3) - 1); - fmov__double_to_bank(state, map, m, n); - return DECODE__DEFINED; + if (state->fpscr.bits.sz == 1) { + uint32_t m = (code >> 5) & ((1 << 3) - 1); + uint32_t n = (code >> 9) & ((1 << 3) - 1); + fmov__double_to_bank(state, map, m, n); + return DECODE__DEFINED; + } else break; } case 0b1111000100011100: // FMOV XDm,XDn { - uint32_t m = (code >> 5) & ((1 << 3) - 1); - uint32_t n = (code >> 9) & ((1 << 3) - 1); - fmov__source_and_destination_operands_bank(state, map, m, n); - return DECODE__DEFINED; + if (state->fpscr.bits.sz == 1) { + uint32_t m = (code >> 5) & ((1 << 3) - 1); + uint32_t n = (code >> 9) & ((1 << 3) - 1); + fmov__source_and_destination_operands_bank(state, map, m, n); + return DECODE__DEFINED; + } else break; } } switch (code & 0b1111000100001111) { case 0b1111000000000110: // FMOV @(R0,Rm),DRn { - uint32_t m = (code >> 4) & ((1 << 4) - 1); - uint32_t n = (code >> 9) & ((1 << 3) - 1); - fmov__load_indexed_register_indirect_double(state, map, m, n); - return DECODE__DEFINED; + if (state->fpscr.bits.sz == 1) { + uint32_t m = (code >> 4) & ((1 << 4) - 1); + uint32_t n = (code >> 9) & ((1 << 3) - 1); + fmov__load_indexed_register_indirect_double(state, map, m, n); + return DECODE__DEFINED; + } else break; } case 0b1111000000001000: // FMOV @Rm,DRn { - uint32_t m = (code >> 4) & ((1 << 4) - 1); - uint32_t n = (code >> 9) & ((1 << 3) - 1); - fmov__load_register_direct_data_transfer_double(state, map, m, n); - return DECODE__DEFINED; + if (state->fpscr.bits.sz == 1) { + uint32_t m = (code >> 4) & ((1 << 4) - 1); + uint32_t n = (code >> 9) & ((1 << 3) - 1); + fmov__load_register_direct_data_transfer_double(state, map, m, n); + return DECODE__DEFINED; + } else break; } case 0b1111000000001001: // FMOV @Rm+,DRn { - uint32_t m = (code >> 4) & ((1 << 4) - 1); - uint32_t n = (code >> 9) & ((1 << 3) - 1); - fmov__load_direct_data_transfer_from_register_double(state, map, m, n); - return DECODE__DEFINED; + if (state->fpscr.bits.sz == 1) { + uint32_t m = (code >> 4) & ((1 << 4) - 1); + uint32_t n = (code >> 9) & ((1 << 3) - 1); + fmov__load_direct_data_transfer_from_register_double(state, map, m, n); + return DECODE__DEFINED; + } else break; } case 0b1111000100000110: // FMOV @(R0,Rm),XDn { - uint32_t m = (code >> 4) & ((1 << 4) - 1); - uint32_t n = (code >> 9) & ((1 << 3) - 1); - fmov__load_indexed_register_indirect_bank(state, map, m, n); - return DECODE__DEFINED; + if (state->fpscr.bits.sz == 1) { + uint32_t m = (code >> 4) & ((1 << 4) - 1); + uint32_t n = (code >> 9) & ((1 << 3) - 1); + fmov__load_indexed_register_indirect_bank(state, map, m, n); + return DECODE__DEFINED; + } else break; } case 0b1111000100001000: // FMOV @Rm,XDn { - uint32_t m = (code >> 4) & ((1 << 4) - 1); - uint32_t n = (code >> 9) & ((1 << 3) - 1); - fmov__load_register_direct_data_transfer_bank(state, map, m, n); - return DECODE__DEFINED; + if (state->fpscr.bits.sz == 1) { + uint32_t m = (code >> 4) & ((1 << 4) - 1); + uint32_t n = (code >> 9) & ((1 << 3) - 1); + fmov__load_register_direct_data_transfer_bank(state, map, m, n); + return DECODE__DEFINED; + } else break; } case 0b1111000100001001: // FMOV @Rm+,XDn { - uint32_t m = (code >> 4) & ((1 << 4) - 1); - uint32_t n = (code >> 9) & ((1 << 3) - 1); - fmov__load_direct_data_transfer_from_register_bank(state, map, m, n); - return DECODE__DEFINED; + if (state->fpscr.bits.sz == 1) { + uint32_t m = (code >> 4) & ((1 << 4) - 1); + uint32_t n = (code >> 9) & ((1 << 3) - 1); + fmov__load_direct_data_transfer_from_register_bank(state, map, m, n); + return DECODE__DEFINED; + } else break; } } switch (code & 0b1111000000011111) { case 0b1111000000000111: // FMOV DRm,@(R0,Rn) { - uint32_t m = (code >> 5) & ((1 << 3) - 1); - uint32_t n = (code >> 8) & ((1 << 4) - 1); - fmov__store_indexed_register_indirect_double(state, map, m, n); - return DECODE__DEFINED; + if (state->fpscr.bits.sz == 1) { + uint32_t m = (code >> 5) & ((1 << 3) - 1); + uint32_t n = (code >> 8) & ((1 << 4) - 1); + fmov__store_indexed_register_indirect_double(state, map, m, n); + return DECODE__DEFINED; + } else break; } case 0b1111000000001010: // FMOV DRm,@Rn { - uint32_t m = (code >> 5) & ((1 << 3) - 1); - uint32_t n = (code >> 8) & ((1 << 4) - 1); - fmov__store_register_direct_data_transfer_double(state, map, m, n); - return DECODE__DEFINED; + if (state->fpscr.bits.sz == 1) { + uint32_t m = (code >> 5) & ((1 << 3) - 1); + uint32_t n = (code >> 8) & ((1 << 4) - 1); + fmov__store_register_direct_data_transfer_double(state, map, m, n); + return DECODE__DEFINED; + } else break; } case 0b1111000000001011: // FMOV DRm,@-Rn { - uint32_t m = (code >> 5) & ((1 << 3) - 1); - uint32_t n = (code >> 8) & ((1 << 4) - 1); - fmov__store_direct_data_transfer_from_register_double(state, map, m, n); - return DECODE__DEFINED; + if (state->fpscr.bits.sz == 1) { + uint32_t m = (code >> 5) & ((1 << 3) - 1); + uint32_t n = (code >> 8) & ((1 << 4) - 1); + fmov__store_direct_data_transfer_from_register_double(state, map, m, n); + return DECODE__DEFINED; + } else break; } case 0b1111000000010111: // FMOV XDm,@(R0,Rn) { - uint32_t m = (code >> 5) & ((1 << 3) - 1); - uint32_t n = (code >> 8) & ((1 << 4) - 1); - fmov__store_indexed_register_indirect_bank(state, map, m, n); - return DECODE__DEFINED; + if (state->fpscr.bits.sz == 1) { + uint32_t m = (code >> 5) & ((1 << 3) - 1); + uint32_t n = (code >> 8) & ((1 << 4) - 1); + fmov__store_indexed_register_indirect_bank(state, map, m, n); + return DECODE__DEFINED; + } else break; } case 0b1111000000011010: // FMOV XDm,@Rn { - uint32_t m = (code >> 5) & ((1 << 3) - 1); - uint32_t n = (code >> 8) & ((1 << 4) - 1); - fmov__store_register_direct_data_transfer_bank(state, map, m, n); - return DECODE__DEFINED; + if (state->fpscr.bits.sz == 1) { + uint32_t m = (code >> 5) & ((1 << 3) - 1); + uint32_t n = (code >> 8) & ((1 << 4) - 1); + fmov__store_register_direct_data_transfer_bank(state, map, m, n); + return DECODE__DEFINED; + } else break; } case 0b1111000000011011: // FMOV XDm,@-Rn { - uint32_t m = (code >> 5) & ((1 << 3) - 1); - uint32_t n = (code >> 8) & ((1 << 4) - 1); - fmov__store_direct_data_transfer_from_register_bank(state, map, m, n); - return DECODE__DEFINED; + if (state->fpscr.bits.sz == 1) { + uint32_t m = (code >> 5) & ((1 << 3) - 1); + uint32_t n = (code >> 8) & ((1 << 4) - 1); + fmov__store_direct_data_transfer_from_register_bank(state, map, m, n); + return DECODE__DEFINED; + } else break; } } switch (code & 0b1111000111111111) { case 0b1111000000101101: // FLOAT FPUL,DRn { - uint32_t n = (code >> 9) & ((1 << 3) - 1); - float__fpul_to_drn(state, map, n); - return DECODE__DEFINED; + if (state->fpscr.bits.pr == 1) { + uint32_t n = (code >> 9) & ((1 << 3) - 1); + float__fpul_to_drn(state, map, n); + return DECODE__DEFINED; + } else break; } case 0b1111000000111101: // FTRC DRm,FPUL { - uint32_t m = (code >> 9) & ((1 << 3) - 1); - ftrc__drm_to_fpul(state, map, m); - return DECODE__DEFINED; + if (state->fpscr.bits.pr == 1) { + uint32_t m = (code >> 9) & ((1 << 3) - 1); + ftrc__drm_to_fpul(state, map, m); + return DECODE__DEFINED; + } else break; } case 0b1111000001001101: // FNEG DRn { - uint32_t n = (code >> 9) & ((1 << 3) - 1); - fneg__destination_operand_only_double(state, map, n); - return DECODE__DEFINED; + if (state->fpscr.bits.pr == 1) { + uint32_t n = (code >> 9) & ((1 << 3) - 1); + fneg__destination_operand_only_double(state, map, n); + return DECODE__DEFINED; + } else break; } case 0b1111000001011101: // FABS DRn { - uint32_t n = (code >> 9) & ((1 << 3) - 1); - fabs__destination_operand_only_double(state, map, n); - return DECODE__DEFINED; + if (state->fpscr.bits.pr == 1) { + uint32_t n = (code >> 9) & ((1 << 3) - 1); + fabs__destination_operand_only_double(state, map, n); + return DECODE__DEFINED; + } else break; } case 0b1111000001101101: // FSQRT DRn { - uint32_t n = (code >> 9) & ((1 << 3) - 1); - fsqrt__destination_operand_only_double(state, map, n); - return DECODE__DEFINED; + if (state->fpscr.bits.pr == 1) { + uint32_t n = (code >> 9) & ((1 << 3) - 1); + fsqrt__destination_operand_only_double(state, map, n); + return DECODE__DEFINED; + } else break; } case 0b1111000010101101: // FCNVSD FPUL,DRn { diff --git a/c/decode_print.c b/c/decode_print.c index d25fda1..e0727ef 100644 --- a/c/decode_print.c +++ b/c/decode_print.c @@ -521,107 +521,133 @@ enum decode_status decode_and_print_instruction(struct architectural_state * sta } case 0b1111000000000000: // FADD FRm,FRn { - uint32_t m = (code >> 4) & ((1 << 4) - 1); - uint32_t n = (code >> 8) & ((1 << 4) - 1); - snprintf(operand_buf, size, "FR%d,FR%d", m, n); - *instruction_buf = "FADD"; - return DECODE__DEFINED; + if (state->fpscr.bits.pr == 0) { + uint32_t m = (code >> 4) & ((1 << 4) - 1); + uint32_t n = (code >> 8) & ((1 << 4) - 1); + snprintf(operand_buf, size, "FR%d,FR%d", m, n); + *instruction_buf = "FADD"; + return DECODE__DEFINED; + } else break; } case 0b1111000000000001: // FSUB FRm,FRn { - uint32_t m = (code >> 4) & ((1 << 4) - 1); - uint32_t n = (code >> 8) & ((1 << 4) - 1); - snprintf(operand_buf, size, "FR%d,FR%d", m, n); - *instruction_buf = "FSUB"; - return DECODE__DEFINED; + if (state->fpscr.bits.pr == 0) { + uint32_t m = (code >> 4) & ((1 << 4) - 1); + uint32_t n = (code >> 8) & ((1 << 4) - 1); + snprintf(operand_buf, size, "FR%d,FR%d", m, n); + *instruction_buf = "FSUB"; + return DECODE__DEFINED; + } else break; } case 0b1111000000000010: // FMUL FRm,FRn { - uint32_t m = (code >> 4) & ((1 << 4) - 1); - uint32_t n = (code >> 8) & ((1 << 4) - 1); - snprintf(operand_buf, size, "FR%d,FR%d", m, n); - *instruction_buf = "FMUL"; - return DECODE__DEFINED; + if (state->fpscr.bits.pr == 0) { + uint32_t m = (code >> 4) & ((1 << 4) - 1); + uint32_t n = (code >> 8) & ((1 << 4) - 1); + snprintf(operand_buf, size, "FR%d,FR%d", m, n); + *instruction_buf = "FMUL"; + return DECODE__DEFINED; + } else break; } case 0b1111000000000011: // FDIV FRm,FRn { - uint32_t m = (code >> 4) & ((1 << 4) - 1); - uint32_t n = (code >> 8) & ((1 << 4) - 1); - snprintf(operand_buf, size, "FR%d,FR%d", m, n); - *instruction_buf = "FDIV"; - return DECODE__DEFINED; + if (state->fpscr.bits.pr == 0) { + uint32_t m = (code >> 4) & ((1 << 4) - 1); + uint32_t n = (code >> 8) & ((1 << 4) - 1); + snprintf(operand_buf, size, "FR%d,FR%d", m, n); + *instruction_buf = "FDIV"; + return DECODE__DEFINED; + } else break; } case 0b1111000000000100: // FCMP/EQ FRm,FRn { - uint32_t m = (code >> 4) & ((1 << 4) - 1); - uint32_t n = (code >> 8) & ((1 << 4) - 1); - snprintf(operand_buf, size, "FR%d,FR%d", m, n); - *instruction_buf = "FCMP/EQ"; - return DECODE__DEFINED; + if (state->fpscr.bits.pr == 0) { + uint32_t m = (code >> 4) & ((1 << 4) - 1); + uint32_t n = (code >> 8) & ((1 << 4) - 1); + snprintf(operand_buf, size, "FR%d,FR%d", m, n); + *instruction_buf = "FCMP/EQ"; + return DECODE__DEFINED; + } else break; } case 0b1111000000000101: // FCMP/GT FRm,FRn { - uint32_t m = (code >> 4) & ((1 << 4) - 1); - uint32_t n = (code >> 8) & ((1 << 4) - 1); - snprintf(operand_buf, size, "FR%d,FR%d", m, n); - *instruction_buf = "FCMP/GT"; - return DECODE__DEFINED; + if (state->fpscr.bits.pr == 0) { + uint32_t m = (code >> 4) & ((1 << 4) - 1); + uint32_t n = (code >> 8) & ((1 << 4) - 1); + snprintf(operand_buf, size, "FR%d,FR%d", m, n); + *instruction_buf = "FCMP/GT"; + return DECODE__DEFINED; + } else break; } case 0b1111000000000110: // FMOV.S @(R0,Rm),FRn { - uint32_t m = (code >> 4) & ((1 << 4) - 1); - uint32_t n = (code >> 8) & ((1 << 4) - 1); - snprintf(operand_buf, size, "@(R0,R%d),FR%d", m, n); - *instruction_buf = "FMOV.S"; - return DECODE__DEFINED; + if (state->fpscr.bits.sz == 0) { + uint32_t m = (code >> 4) & ((1 << 4) - 1); + uint32_t n = (code >> 8) & ((1 << 4) - 1); + snprintf(operand_buf, size, "@(R0,R%d),FR%d", m, n); + *instruction_buf = "FMOV.S"; + return DECODE__DEFINED; + } else break; } case 0b1111000000000111: // FMOV.S FRm,@(R0,Rn) { - uint32_t m = (code >> 4) & ((1 << 4) - 1); - uint32_t n = (code >> 8) & ((1 << 4) - 1); - snprintf(operand_buf, size, "FR%d,@(R0,R%d)", m, n); - *instruction_buf = "FMOV.S"; - return DECODE__DEFINED; + if (state->fpscr.bits.sz == 0) { + uint32_t m = (code >> 4) & ((1 << 4) - 1); + uint32_t n = (code >> 8) & ((1 << 4) - 1); + snprintf(operand_buf, size, "FR%d,@(R0,R%d)", m, n); + *instruction_buf = "FMOV.S"; + return DECODE__DEFINED; + } else break; } case 0b1111000000001000: // FMOV.S @Rm,FRn { - uint32_t m = (code >> 4) & ((1 << 4) - 1); - uint32_t n = (code >> 8) & ((1 << 4) - 1); - snprintf(operand_buf, size, "@R%d,FR%d", m, n); - *instruction_buf = "FMOV.S"; - return DECODE__DEFINED; + if (state->fpscr.bits.sz == 0) { + uint32_t m = (code >> 4) & ((1 << 4) - 1); + uint32_t n = (code >> 8) & ((1 << 4) - 1); + snprintf(operand_buf, size, "@R%d,FR%d", m, n); + *instruction_buf = "FMOV.S"; + return DECODE__DEFINED; + } else break; } case 0b1111000000001001: // FMOV.S @Rm+,FRn { - uint32_t m = (code >> 4) & ((1 << 4) - 1); - uint32_t n = (code >> 8) & ((1 << 4) - 1); - snprintf(operand_buf, size, "@R%d+,FR%d", m, n); - *instruction_buf = "FMOV.S"; - return DECODE__DEFINED; + if (state->fpscr.bits.sz == 0) { + uint32_t m = (code >> 4) & ((1 << 4) - 1); + uint32_t n = (code >> 8) & ((1 << 4) - 1); + snprintf(operand_buf, size, "@R%d+,FR%d", m, n); + *instruction_buf = "FMOV.S"; + return DECODE__DEFINED; + } else break; } case 0b1111000000001010: // FMOV.S FRm,@Rn { - uint32_t m = (code >> 4) & ((1 << 4) - 1); - uint32_t n = (code >> 8) & ((1 << 4) - 1); - snprintf(operand_buf, size, "FR%d,@R%d", m, n); - *instruction_buf = "FMOV.S"; - return DECODE__DEFINED; + if (state->fpscr.bits.sz == 0) { + uint32_t m = (code >> 4) & ((1 << 4) - 1); + uint32_t n = (code >> 8) & ((1 << 4) - 1); + snprintf(operand_buf, size, "FR%d,@R%d", m, n); + *instruction_buf = "FMOV.S"; + return DECODE__DEFINED; + } else break; } case 0b1111000000001011: // FMOV.S FRm,@-Rn { - uint32_t m = (code >> 4) & ((1 << 4) - 1); - uint32_t n = (code >> 8) & ((1 << 4) - 1); - snprintf(operand_buf, size, "FR%d,@-R%d", m, n); - *instruction_buf = "FMOV.S"; - return DECODE__DEFINED; + if (state->fpscr.bits.sz == 0) { + uint32_t m = (code >> 4) & ((1 << 4) - 1); + uint32_t n = (code >> 8) & ((1 << 4) - 1); + snprintf(operand_buf, size, "FR%d,@-R%d", m, n); + *instruction_buf = "FMOV.S"; + return DECODE__DEFINED; + } else break; } case 0b1111000000001100: // FMOV FRm,FRn { - uint32_t m = (code >> 4) & ((1 << 4) - 1); - uint32_t n = (code >> 8) & ((1 << 4) - 1); - snprintf(operand_buf, size, "FR%d,FR%d", m, n); - *instruction_buf = "FMOV"; - return DECODE__DEFINED; + if (state->fpscr.bits.sz == 0) { + uint32_t m = (code >> 4) & ((1 << 4) - 1); + uint32_t n = (code >> 8) & ((1 << 4) - 1); + snprintf(operand_buf, size, "FR%d,FR%d", m, n); + *instruction_buf = "FMOV"; + return DECODE__DEFINED; + } else break; } case 0b1111000000001110: // FMAC FR0,FRm,FRn { @@ -1313,38 +1339,48 @@ enum decode_status decode_and_print_instruction(struct architectural_state * sta } case 0b1111000000101101: // FLOAT FPUL,FRn { - uint32_t n = (code >> 8) & ((1 << 4) - 1); - snprintf(operand_buf, size, "FPUL,FR%d", n); - *instruction_buf = "FLOAT"; - return DECODE__DEFINED; + if (state->fpscr.bits.pr == 0) { + uint32_t n = (code >> 8) & ((1 << 4) - 1); + snprintf(operand_buf, size, "FPUL,FR%d", n); + *instruction_buf = "FLOAT"; + return DECODE__DEFINED; + } else break; } case 0b1111000000111101: // FTRC FRm,FPUL { - uint32_t m = (code >> 8) & ((1 << 4) - 1); - snprintf(operand_buf, size, "FR%d,FPUL", m); - *instruction_buf = "FTRC"; - return DECODE__DEFINED; + if (state->fpscr.bits.pr == 0) { + uint32_t m = (code >> 8) & ((1 << 4) - 1); + snprintf(operand_buf, size, "FR%d,FPUL", m); + *instruction_buf = "FTRC"; + return DECODE__DEFINED; + } else break; } case 0b1111000001001101: // FNEG FRn { - uint32_t n = (code >> 8) & ((1 << 4) - 1); - snprintf(operand_buf, size, "FR%d", n); - *instruction_buf = "FNEG"; - return DECODE__DEFINED; + if (state->fpscr.bits.pr == 0) { + uint32_t n = (code >> 8) & ((1 << 4) - 1); + snprintf(operand_buf, size, "FR%d", n); + *instruction_buf = "FNEG"; + return DECODE__DEFINED; + } else break; } case 0b1111000001011101: // FABS FRn { - uint32_t n = (code >> 8) & ((1 << 4) - 1); - snprintf(operand_buf, size, "FR%d", n); - *instruction_buf = "FABS"; - return DECODE__DEFINED; + if (state->fpscr.bits.pr == 0) { + uint32_t n = (code >> 8) & ((1 << 4) - 1); + snprintf(operand_buf, size, "FR%d", n); + *instruction_buf = "FABS"; + return DECODE__DEFINED; + } else break; } case 0b1111000001101101: // FSQRT FRn { - uint32_t n = (code >> 8) & ((1 << 4) - 1); - snprintf(operand_buf, size, "FR%d", n); - *instruction_buf = "FSQRT"; - return DECODE__DEFINED; + if (state->fpscr.bits.pr == 0) { + uint32_t n = (code >> 8) & ((1 << 4) - 1); + snprintf(operand_buf, size, "FR%d", n); + *instruction_buf = "FSQRT"; + return DECODE__DEFINED; + } else break; } case 0b1111000010001101: // FLDI0 FRn { @@ -1472,220 +1508,274 @@ enum decode_status decode_and_print_instruction(struct architectural_state * sta switch (code & 0b1111000100011111) { case 0b1111000000000000: // FADD DRm,DRn { - uint32_t m = (code >> 5) & ((1 << 3) - 1); - uint32_t n = (code >> 9) & ((1 << 3) - 1); - snprintf(operand_buf, size, "DR%d,DR%d", m, n); - *instruction_buf = "FADD"; - return DECODE__DEFINED; + if (state->fpscr.bits.pr == 1) { + uint32_t m = (code >> 5) & ((1 << 3) - 1); + uint32_t n = (code >> 9) & ((1 << 3) - 1); + snprintf(operand_buf, size, "DR%d,DR%d", m, n); + *instruction_buf = "FADD"; + return DECODE__DEFINED; + } else break; } case 0b1111000000000001: // FSUB DRm,DRn { - uint32_t m = (code >> 5) & ((1 << 3) - 1); - uint32_t n = (code >> 9) & ((1 << 3) - 1); - snprintf(operand_buf, size, "DR%d,DR%d", m, n); - *instruction_buf = "FSUB"; - return DECODE__DEFINED; + if (state->fpscr.bits.pr == 1) { + uint32_t m = (code >> 5) & ((1 << 3) - 1); + uint32_t n = (code >> 9) & ((1 << 3) - 1); + snprintf(operand_buf, size, "DR%d,DR%d", m, n); + *instruction_buf = "FSUB"; + return DECODE__DEFINED; + } else break; } case 0b1111000000000010: // FMUL DRm,DRn { - uint32_t m = (code >> 5) & ((1 << 3) - 1); - uint32_t n = (code >> 9) & ((1 << 3) - 1); - snprintf(operand_buf, size, "DR%d,DR%d", m, n); - *instruction_buf = "FMUL"; - return DECODE__DEFINED; + if (state->fpscr.bits.pr == 1) { + uint32_t m = (code >> 5) & ((1 << 3) - 1); + uint32_t n = (code >> 9) & ((1 << 3) - 1); + snprintf(operand_buf, size, "DR%d,DR%d", m, n); + *instruction_buf = "FMUL"; + return DECODE__DEFINED; + } else break; } case 0b1111000000000011: // FDIV DRm,DRn { - uint32_t m = (code >> 5) & ((1 << 3) - 1); - uint32_t n = (code >> 9) & ((1 << 3) - 1); - snprintf(operand_buf, size, "DR%d,DR%d", m, n); - *instruction_buf = "FDIV"; - return DECODE__DEFINED; + if (state->fpscr.bits.pr == 1) { + uint32_t m = (code >> 5) & ((1 << 3) - 1); + uint32_t n = (code >> 9) & ((1 << 3) - 1); + snprintf(operand_buf, size, "DR%d,DR%d", m, n); + *instruction_buf = "FDIV"; + return DECODE__DEFINED; + } else break; } case 0b1111000000000100: // FCMP/EQ DRm,DRn { - uint32_t m = (code >> 5) & ((1 << 3) - 1); - uint32_t n = (code >> 9) & ((1 << 3) - 1); - snprintf(operand_buf, size, "DR%d,DR%d", m, n); - *instruction_buf = "FCMP/EQ"; - return DECODE__DEFINED; + if (state->fpscr.bits.pr == 1) { + uint32_t m = (code >> 5) & ((1 << 3) - 1); + uint32_t n = (code >> 9) & ((1 << 3) - 1); + snprintf(operand_buf, size, "DR%d,DR%d", m, n); + *instruction_buf = "FCMP/EQ"; + return DECODE__DEFINED; + } else break; } case 0b1111000000000101: // FCMP/GT DRm,DRn { - uint32_t m = (code >> 5) & ((1 << 3) - 1); - uint32_t n = (code >> 9) & ((1 << 3) - 1); - snprintf(operand_buf, size, "DR%d,DR%d", m, n); - *instruction_buf = "FCMP/GT"; - return DECODE__DEFINED; + if (state->fpscr.bits.pr == 1) { + uint32_t m = (code >> 5) & ((1 << 3) - 1); + uint32_t n = (code >> 9) & ((1 << 3) - 1); + snprintf(operand_buf, size, "DR%d,DR%d", m, n); + *instruction_buf = "FCMP/GT"; + return DECODE__DEFINED; + } else break; } case 0b1111000000001100: // FMOV DRm,DRn { - uint32_t m = (code >> 5) & ((1 << 3) - 1); - uint32_t n = (code >> 9) & ((1 << 3) - 1); - snprintf(operand_buf, size, "DR%d,DR%d", m, n); - *instruction_buf = "FMOV"; - return DECODE__DEFINED; + if (state->fpscr.bits.sz == 1) { + uint32_t m = (code >> 5) & ((1 << 3) - 1); + uint32_t n = (code >> 9) & ((1 << 3) - 1); + snprintf(operand_buf, size, "DR%d,DR%d", m, n); + *instruction_buf = "FMOV"; + return DECODE__DEFINED; + } else break; } case 0b1111000000011100: // FMOV XDm,DRn { - uint32_t m = (code >> 5) & ((1 << 3) - 1); - uint32_t n = (code >> 9) & ((1 << 3) - 1); - snprintf(operand_buf, size, "XD%d,DR%d", m, n); - *instruction_buf = "FMOV"; - return DECODE__DEFINED; + if (state->fpscr.bits.sz == 1) { + uint32_t m = (code >> 5) & ((1 << 3) - 1); + uint32_t n = (code >> 9) & ((1 << 3) - 1); + snprintf(operand_buf, size, "XD%d,DR%d", m, n); + *instruction_buf = "FMOV"; + return DECODE__DEFINED; + } else break; } case 0b1111000100001100: // FMOV DRm,XDn { - uint32_t m = (code >> 5) & ((1 << 3) - 1); - uint32_t n = (code >> 9) & ((1 << 3) - 1); - snprintf(operand_buf, size, "DR%d,XD%d", m, n); - *instruction_buf = "FMOV"; - return DECODE__DEFINED; + if (state->fpscr.bits.sz == 1) { + uint32_t m = (code >> 5) & ((1 << 3) - 1); + uint32_t n = (code >> 9) & ((1 << 3) - 1); + snprintf(operand_buf, size, "DR%d,XD%d", m, n); + *instruction_buf = "FMOV"; + return DECODE__DEFINED; + } else break; } case 0b1111000100011100: // FMOV XDm,XDn { - uint32_t m = (code >> 5) & ((1 << 3) - 1); - uint32_t n = (code >> 9) & ((1 << 3) - 1); - snprintf(operand_buf, size, "XD%d,XD%d", m, n); - *instruction_buf = "FMOV"; - return DECODE__DEFINED; + if (state->fpscr.bits.sz == 1) { + uint32_t m = (code >> 5) & ((1 << 3) - 1); + uint32_t n = (code >> 9) & ((1 << 3) - 1); + snprintf(operand_buf, size, "XD%d,XD%d", m, n); + *instruction_buf = "FMOV"; + return DECODE__DEFINED; + } else break; } } switch (code & 0b1111000100001111) { case 0b1111000000000110: // FMOV @(R0,Rm),DRn { - uint32_t m = (code >> 4) & ((1 << 4) - 1); - uint32_t n = (code >> 9) & ((1 << 3) - 1); - snprintf(operand_buf, size, "@(R0,R%d),DR%d", m, n); - *instruction_buf = "FMOV"; - return DECODE__DEFINED; + if (state->fpscr.bits.sz == 1) { + uint32_t m = (code >> 4) & ((1 << 4) - 1); + uint32_t n = (code >> 9) & ((1 << 3) - 1); + snprintf(operand_buf, size, "@(R0,R%d),DR%d", m, n); + *instruction_buf = "FMOV"; + return DECODE__DEFINED; + } else break; } case 0b1111000000001000: // FMOV @Rm,DRn { - uint32_t m = (code >> 4) & ((1 << 4) - 1); - uint32_t n = (code >> 9) & ((1 << 3) - 1); - snprintf(operand_buf, size, "@R%d,DR%d", m, n); - *instruction_buf = "FMOV"; - return DECODE__DEFINED; + if (state->fpscr.bits.sz == 1) { + uint32_t m = (code >> 4) & ((1 << 4) - 1); + uint32_t n = (code >> 9) & ((1 << 3) - 1); + snprintf(operand_buf, size, "@R%d,DR%d", m, n); + *instruction_buf = "FMOV"; + return DECODE__DEFINED; + } else break; } case 0b1111000000001001: // FMOV @Rm+,DRn { - uint32_t m = (code >> 4) & ((1 << 4) - 1); - uint32_t n = (code >> 9) & ((1 << 3) - 1); - snprintf(operand_buf, size, "@R%d+,DR%d", m, n); - *instruction_buf = "FMOV"; - return DECODE__DEFINED; + if (state->fpscr.bits.sz == 1) { + uint32_t m = (code >> 4) & ((1 << 4) - 1); + uint32_t n = (code >> 9) & ((1 << 3) - 1); + snprintf(operand_buf, size, "@R%d+,DR%d", m, n); + *instruction_buf = "FMOV"; + return DECODE__DEFINED; + } else break; } case 0b1111000100000110: // FMOV @(R0,Rm),XDn { - uint32_t m = (code >> 4) & ((1 << 4) - 1); - uint32_t n = (code >> 9) & ((1 << 3) - 1); - snprintf(operand_buf, size, "@(R0,R%d),XD%d", m, n); - *instruction_buf = "FMOV"; - return DECODE__DEFINED; + if (state->fpscr.bits.sz == 1) { + uint32_t m = (code >> 4) & ((1 << 4) - 1); + uint32_t n = (code >> 9) & ((1 << 3) - 1); + snprintf(operand_buf, size, "@(R0,R%d),XD%d", m, n); + *instruction_buf = "FMOV"; + return DECODE__DEFINED; + } else break; } case 0b1111000100001000: // FMOV @Rm,XDn { - uint32_t m = (code >> 4) & ((1 << 4) - 1); - uint32_t n = (code >> 9) & ((1 << 3) - 1); - snprintf(operand_buf, size, "@R%d,XD%d", m, n); - *instruction_buf = "FMOV"; - return DECODE__DEFINED; + if (state->fpscr.bits.sz == 1) { + uint32_t m = (code >> 4) & ((1 << 4) - 1); + uint32_t n = (code >> 9) & ((1 << 3) - 1); + snprintf(operand_buf, size, "@R%d,XD%d", m, n); + *instruction_buf = "FMOV"; + return DECODE__DEFINED; + } else break; } case 0b1111000100001001: // FMOV @Rm+,XDn { - uint32_t m = (code >> 4) & ((1 << 4) - 1); - uint32_t n = (code >> 9) & ((1 << 3) - 1); - snprintf(operand_buf, size, "@R%d+,XD%d", m, n); - *instruction_buf = "FMOV"; - return DECODE__DEFINED; + if (state->fpscr.bits.sz == 1) { + uint32_t m = (code >> 4) & ((1 << 4) - 1); + uint32_t n = (code >> 9) & ((1 << 3) - 1); + snprintf(operand_buf, size, "@R%d+,XD%d", m, n); + *instruction_buf = "FMOV"; + return DECODE__DEFINED; + } else break; } } switch (code & 0b1111000000011111) { case 0b1111000000000111: // FMOV DRm,@(R0,Rn) { - uint32_t m = (code >> 5) & ((1 << 3) - 1); - uint32_t n = (code >> 8) & ((1 << 4) - 1); - snprintf(operand_buf, size, "DR%d,@(R0,R%d)", m, n); - *instruction_buf = "FMOV"; - return DECODE__DEFINED; + if (state->fpscr.bits.sz == 1) { + uint32_t m = (code >> 5) & ((1 << 3) - 1); + uint32_t n = (code >> 8) & ((1 << 4) - 1); + snprintf(operand_buf, size, "DR%d,@(R0,R%d)", m, n); + *instruction_buf = "FMOV"; + return DECODE__DEFINED; + } else break; } case 0b1111000000001010: // FMOV DRm,@Rn { - uint32_t m = (code >> 5) & ((1 << 3) - 1); - uint32_t n = (code >> 8) & ((1 << 4) - 1); - snprintf(operand_buf, size, "DR%d,@R%d", m, n); - *instruction_buf = "FMOV"; - return DECODE__DEFINED; + if (state->fpscr.bits.sz == 1) { + uint32_t m = (code >> 5) & ((1 << 3) - 1); + uint32_t n = (code >> 8) & ((1 << 4) - 1); + snprintf(operand_buf, size, "DR%d,@R%d", m, n); + *instruction_buf = "FMOV"; + return DECODE__DEFINED; + } else break; } case 0b1111000000001011: // FMOV DRm,@-Rn { - uint32_t m = (code >> 5) & ((1 << 3) - 1); - uint32_t n = (code >> 8) & ((1 << 4) - 1); - snprintf(operand_buf, size, "DR%d,@-R%d", m, n); - *instruction_buf = "FMOV"; - return DECODE__DEFINED; + if (state->fpscr.bits.sz == 1) { + uint32_t m = (code >> 5) & ((1 << 3) - 1); + uint32_t n = (code >> 8) & ((1 << 4) - 1); + snprintf(operand_buf, size, "DR%d,@-R%d", m, n); + *instruction_buf = "FMOV"; + return DECODE__DEFINED; + } else break; } case 0b1111000000010111: // FMOV XDm,@(R0,Rn) { - uint32_t m = (code >> 5) & ((1 << 3) - 1); - uint32_t n = (code >> 8) & ((1 << 4) - 1); - snprintf(operand_buf, size, "XD%d,@(R0,R%d)", m, n); - *instruction_buf = "FMOV"; - return DECODE__DEFINED; + if (state->fpscr.bits.sz == 1) { + uint32_t m = (code >> 5) & ((1 << 3) - 1); + uint32_t n = (code >> 8) & ((1 << 4) - 1); + snprintf(operand_buf, size, "XD%d,@(R0,R%d)", m, n); + *instruction_buf = "FMOV"; + return DECODE__DEFINED; + } else break; } case 0b1111000000011010: // FMOV XDm,@Rn { - uint32_t m = (code >> 5) & ((1 << 3) - 1); - uint32_t n = (code >> 8) & ((1 << 4) - 1); - snprintf(operand_buf, size, "XD%d,@R%d", m, n); - *instruction_buf = "FMOV"; - return DECODE__DEFINED; + if (state->fpscr.bits.sz == 1) { + uint32_t m = (code >> 5) & ((1 << 3) - 1); + uint32_t n = (code >> 8) & ((1 << 4) - 1); + snprintf(operand_buf, size, "XD%d,@R%d", m, n); + *instruction_buf = "FMOV"; + return DECODE__DEFINED; + } else break; } case 0b1111000000011011: // FMOV XDm,@-Rn { - uint32_t m = (code >> 5) & ((1 << 3) - 1); - uint32_t n = (code >> 8) & ((1 << 4) - 1); - snprintf(operand_buf, size, "XD%d,@-R%d", m, n); - *instruction_buf = "FMOV"; - return DECODE__DEFINED; + if (state->fpscr.bits.sz == 1) { + uint32_t m = (code >> 5) & ((1 << 3) - 1); + uint32_t n = (code >> 8) & ((1 << 4) - 1); + snprintf(operand_buf, size, "XD%d,@-R%d", m, n); + *instruction_buf = "FMOV"; + return DECODE__DEFINED; + } else break; } } switch (code & 0b1111000111111111) { case 0b1111000000101101: // FLOAT FPUL,DRn { - uint32_t n = (code >> 9) & ((1 << 3) - 1); - snprintf(operand_buf, size, "FPUL,DR%d", n); - *instruction_buf = "FLOAT"; - return DECODE__DEFINED; + if (state->fpscr.bits.pr == 1) { + uint32_t n = (code >> 9) & ((1 << 3) - 1); + snprintf(operand_buf, size, "FPUL,DR%d", n); + *instruction_buf = "FLOAT"; + return DECODE__DEFINED; + } else break; } case 0b1111000000111101: // FTRC DRm,FPUL { - uint32_t m = (code >> 9) & ((1 << 3) - 1); - snprintf(operand_buf, size, "DR%d,FPUL", m); - *instruction_buf = "FTRC"; - return DECODE__DEFINED; + if (state->fpscr.bits.pr == 1) { + uint32_t m = (code >> 9) & ((1 << 3) - 1); + snprintf(operand_buf, size, "DR%d,FPUL", m); + *instruction_buf = "FTRC"; + return DECODE__DEFINED; + } else break; } case 0b1111000001001101: // FNEG DRn { - uint32_t n = (code >> 9) & ((1 << 3) - 1); - snprintf(operand_buf, size, "DR%d", n); - *instruction_buf = "FNEG"; - return DECODE__DEFINED; + if (state->fpscr.bits.pr == 1) { + uint32_t n = (code >> 9) & ((1 << 3) - 1); + snprintf(operand_buf, size, "DR%d", n); + *instruction_buf = "FNEG"; + return DECODE__DEFINED; + } else break; } case 0b1111000001011101: // FABS DRn { - uint32_t n = (code >> 9) & ((1 << 3) - 1); - snprintf(operand_buf, size, "DR%d", n); - *instruction_buf = "FABS"; - return DECODE__DEFINED; + if (state->fpscr.bits.pr == 1) { + uint32_t n = (code >> 9) & ((1 << 3) - 1); + snprintf(operand_buf, size, "DR%d", n); + *instruction_buf = "FABS"; + return DECODE__DEFINED; + } else break; } case 0b1111000001101101: // FSQRT DRn { - uint32_t n = (code >> 9) & ((1 << 3) - 1); - snprintf(operand_buf, size, "DR%d", n); - *instruction_buf = "FSQRT"; - return DECODE__DEFINED; + if (state->fpscr.bits.pr == 1) { + uint32_t n = (code >> 9) & ((1 << 3) - 1); + snprintf(operand_buf, size, "DR%d", n); + *instruction_buf = "FSQRT"; + return DECODE__DEFINED; + } else break; } case 0b1111000010101101: // FCNVSD FPUL,DRn { diff --git a/generate_decoder.py b/generate_decoder.py index d489c1b..93852dd 100644 --- a/generate_decoder.py +++ b/generate_decoder.py @@ -5,6 +5,8 @@ from instruction_table import untabulate_instructions_sh4 from instruction_table import untabulate_instructions_sh2 from instruction_function_name import instruction_function_name from generate import renderer +from generate_impl import parse_header +from generate_impl import read_ins_source from disabled_instructions import disabled_instructions @@ -41,34 +43,39 @@ def render_execute(ins): variable_args = ", " + ", ".join(ins.variables) if ins.variables else "" yield f"{function_name}(state, map{variable_args});" -def render_mask_switch(body_func, mask, instructions): +def render_mask_switch(body_func, mask, instructions, discriminators): yield f"switch (code & {b16(mask)}) {{" for ins in instructions: yield f"case {b16(ins.code.code_bits)}: // {ins.instruction} {ins.operands}" yield "{" + if (ins.instruction, ins.operands) in discriminators: + (variable, value), = discriminators[(ins.instruction, ins.operands)] + yield f"if (state->fpscr.bits.{variable} == {value}) {{" for variable in ins.variables: operand_var = ins.code.operands[variable] yield f"uint32_t {variable} = (code >> {operand_var.lsb}) & ((1 << {operand_var.length}) - 1);" yield from body_func(ins) yield f"return DECODE__DEFINED;" + if (ins.instruction, ins.operands) in discriminators: + yield "} else break;" yield "}" yield "}" -def render_mask_switches(body_func, by_mask): +def render_mask_switches(body_func, by_mask, discriminators): yield "{" for mask, instructions in by_mask.items(): instructions = sorted(instructions, key=lambda i: i.code.code_bits) - yield from render_mask_switch(body_func, mask, instructions) + yield from render_mask_switch(body_func, mask, instructions, discriminators) yield "return DECODE__UNDEFINED;" yield "}" -def render_decode_and_execute(by_mask): +def render_decode_and_execute(by_mask, discriminators): yield f"enum decode_status decode_and_execute_instruction(struct architectural_state * state, struct memory_map * map, uint16_t code)" - yield from render_mask_switches(render_execute, by_mask) + yield from render_mask_switches(render_execute, by_mask, discriminators) -def render_decode_and_print(by_mask): +def render_decode_and_print(by_mask, discriminators): yield f"enum decode_status decode_and_print_instruction(struct architectural_state * state, struct memory_map * map, uint16_t code, char const ** instruction_buf, char * operand_buf, uint32_t size)" - yield from render_mask_switches(render_print, by_mask) + yield from render_mask_switches(render_print, by_mask, discriminators) def header_execute(): yield '#include "decode_execute.h"' @@ -81,27 +88,78 @@ def header_print(): yield '#include "decode_print.h"' yield "" +s = set() + +def symmetric_available(a): + return { + 'Available only when SZ=0': 'Available only when PR=0', + 'Available only when PR=0': 'Available only when SZ=0', + 'Available only when PR=1 and SZ=0': 'Available only when PR=0 and SZ=1', + 'Available only when PR=0 and SZ=1': 'Available only when PR=1 and SZ=0', + }[a] + +def parse_available(a): + return { + 'Available only when PR=1 and SZ=0': {"pr": 1, "sz": 0}, + 'Available only when SZ=0' : {"sz": 0}, + 'Available only when PR=0' : {"pr": 0}, + 'Available only when PR=0 and SZ=1': {"pr": 0, "sz": 1}, + }[a] + def main(): + dup = set() + + by_instruction_operands = {} + + table = untabulate_instructions_sh4() + for ins1 in table: + buf = read_ins_source(ins1) + _, available, _ = parse_header(buf) + assert (ins1.instruction, ins1.operands) not in by_instruction_operands + by_instruction_operands[(ins1.instruction, ins1.operands)] = (ins1, available) + + for ins2 in table: + if ins1 is ins2: + continue + if ins1.code.code_bits & ins2.code.mask_bits == ins2.code.code_bits: + assert (ins1.instruction, ins1.operands) != (ins2.instruction, ins2.operands) + dup.add(frozenset([(ins1.instruction, ins1.operands), + (ins2.instruction, ins2.operands)])) + + discriminators = {} + + for dup1, dup2 in dup: + ins1, available1 = by_instruction_operands[dup1] + ins2, available2 = by_instruction_operands[dup2] + assert available1 is not None and available2 is not None, (dup1, dup2) + av1 = parse_available(available1) + av2 = parse_available(available2) + assert symmetric_available(available1) != available2, (ins1, available1, ins2, available2) + intersection = set(av1.keys()) & set(av2.keys()) + av1 = tuple((k, v) for k, v in av1.items() if k in intersection) + av2 = tuple((k, v) for k, v in av2.items() if k in intersection) + assert av1 != av2 + discriminators[(ins1.instruction, ins1.operands)] = av1 + discriminators[(ins2.instruction, ins2.operands)] = av2 + by_mask = defaultdict(list) masks = [] - for ins in untabulate_instructions_sh4(): if ins.instruction in disabled_instructions: continue - if ins.code.mask_bits not in masks: masks.append(ins.code.mask_bits) by_mask[ins.code.mask_bits].append(ins) render, out = renderer() render(header_execute()) - render(render_decode_and_execute(by_mask)) + render(render_decode_and_execute(by_mask, discriminators)) with open(sys.argv[1], 'w') as f: f.write(out.getvalue()) render, out = renderer() render(header_print()) - render(render_decode_and_print(by_mask)) + render(render_decode_and_print(by_mask, discriminators)) with open(sys.argv[2], 'w') as f: f.write(out.getvalue()) diff --git a/generate_impl.py b/generate_impl.py index 89eff1e..1ce207d 100644 --- a/generate_impl.py +++ b/generate_impl.py @@ -8,6 +8,7 @@ from ast_transformers import transform_statements from instruction_table import untabulate_instructions_sh4 from instruction_table import untabulate_instructions_sh2 +from instruction_table import unparse_instruction_code from instruction_function_name import instruction_function_name from instruction_file_name import instruction_file_name from instruction_properties import has_delay_slot @@ -17,21 +18,22 @@ from disabled_instructions import disabled_instructions def is_instruction_descriptor(s): return all(c in {'0', '1', 'n', 'm', 'i', 'd'} for c in s) -def parse_file(path): - with open(path) as f: - buf = f.read() - - lines = buf.split('\n', maxsplit=2) - assert len(lines[0]) == 16 and is_instruction_descriptor(lines[0]), lines[0] - - if lines[1].startswith('Available only when'): - buf = lines[2] +def parse_header(buf): + lines = buf.split('\n') + code, available, *rest = lines + assert len(code) == 16 and is_instruction_descriptor(lines[0]), lines[0] + if not available.startswith('Available only when'): + return code, None, '\n'.join([available, *rest]) else: - if len(lines) >= 3: - buf = '\n'.join([lines[1], lines[2]]) - else: - buf = lines[1] + return code, available, '\n'.join(rest) +def read_ins_source(ins): + file_name = instruction_file_name(ins) + src_path = os.path.join("sh4", file_name) + with open(src_path) as f: + return f.read() + +def parse_tokens(buf): lexer = Lexer(buf) while True: @@ -54,9 +56,12 @@ def generate_function_declaration(instruction_name, function_name, variables): yield f"/* {instruction_name} */" yield f"void {function_name}({args})" -def generate_file(instruction_name, function_name, variables, delay_slot, src_path): - print(instruction_name) - tokens = list(parse_file(src_path)) +def generate_file(instruction_name, function_name, ins, delay_slot): + buf = read_ins_source(ins) + code, _available, source = parse_header(buf) + assert code == unparse_instruction_code(ins), (code, unparse_instruction_code(ins)) + + tokens = list(parse_tokens(source)) parser = Parser(tokens) statements = [] while parser.tokens[parser.pos:]: @@ -64,7 +69,7 @@ def generate_file(instruction_name, function_name, variables, delay_slot, src_pa statements = transform_statements(statements) - yield from generate_function_declaration(instruction_name, function_name, variables) + yield from generate_function_declaration(instruction_name, function_name, ins.variables) yield "{" output = [] for statement in statements: @@ -104,10 +109,8 @@ def main(): _name = [ins.instruction, ins.operands] if ins.operands else [ins.instruction] instruction_name = " ".join(_name) function_name = instruction_function_name(ins) - file_name = instruction_file_name(ins) - src_path = os.path.join("sh4", file_name) delay_slot = "true" if has_delay_slot(ins) else "false" - gen = generate_file(instruction_name, function_name, ins.variables, delay_slot, src_path) + gen = generate_file(instruction_name, function_name, ins, delay_slot) output.extend(gen) gen = generate_function_declaration(instruction_name, function_name, ins.variables) diff --git a/python/generate_sh4_directory.py b/python/generate_sh4_directory.py index 098fc38..003ad29 100644 --- a/python/generate_sh4_directory.py +++ b/python/generate_sh4_directory.py @@ -1,14 +1,12 @@ from instruction_table import untabulate_instructions_sh4 +from instruction_table import unparse_instruction_code from instruction_file_name import instruction_file_name for ins in untabulate_instructions_sh4(): - code = list(f'{ins.code.code_bits:016b}') - for operand in ins.code.operands.values(): - for i in range(operand.lsb, operand.lsb + operand.length): - code[15 - i] = operand.operand + code = unparse_instruction_code(ins) file_name = instruction_file_name(ins) path = os.path.join("sh4", file_name) assert not os.path.exists(path) with open(path, 'w') as f: - f.write(''.join(code) + '\n') + f.write(code + '\n') diff --git a/python/instruction_table.py b/python/instruction_table.py index c10e842..69db09b 100644 --- a/python/instruction_table.py +++ b/python/instruction_table.py @@ -4,14 +4,33 @@ from pprint import pprint import os import inspect -@dataclass +@dataclass(frozen=True) +class CodeOperand: + operand: str + lsb: int + length: int + +@dataclass(frozen=True) +class Code: + code_bits: int + mask_bits: int + operands: list[CodeOperand] + +@dataclass(frozen=True) class Instruction: instruction: str operands: str variables: list[str] - code: str + code: Code operation: str +def unparse_instruction_code(ins): + code = list(f'{ins.code.code_bits:016b}') + for operand in ins.code.operands.values(): + for i in range(operand.lsb, operand.lsb + operand.length): + code[15 - i] = operand.operand + return ''.join(code) + _operands = { "Rn", "Rm", @@ -31,18 +50,6 @@ def _b16_str(n): def b16_str(n): return ''.join(_b16_str(n)) -@dataclass -class CodeOperand: - operand: str - lsb: int - length: int - -@dataclass -class Code: - code_bits: int - mask_bits: int - operands: list[CodeOperand] - _operand_bits = { 'i', 'n', @@ -190,9 +197,15 @@ def untabulate_instructions(filename, columns): assert '\t' not in line, line if line and line[0] == ' ': assert len(line.strip()) == len(column("operation").strip()) - instructions[-1].operation = " ".join([ - instructions[-1].operation, line.strip() - ]) + instructions[-1] = Instruction( + instruction = instructions[-1].instruction, + operands = instructions[-1].operands, + variables = instructions[-1].variables, + code = instructions[-1].code, + operation = " ".join([ + instructions[-1].operation, line.strip() + ]) + ) continue instruction = Instruction(*parse_instruction(**dict([ (name, line[start:end].strip())