decode: implement PR- and SZ- instruction decode discrimination
Some SH4 floating point instructions have ambiguous encodings that depend on FPSCR variables. Exhaustively, these are: FMOV XDm,DRn (sz 1) FMOV FRm,FRn (sz 0) FMOV DRm,@(R0,Rn) (sz 1) FMOV.S FRm,@(R0,Rn) (sz 0) FCMP/EQ DRm,DRn (pr 1) FCMP/EQ FRm,FRn (pr 0) FMOV @Rm+,XDn (sz 1) FMOV.S @Rm+,FRn (sz 0) FMOV XDm,@(R0,Rn) (sz 1) FMOV.S FRm,@(R0,Rn) (sz 0) FMUL DRm,DRn (pr 1) FMUL FRm,FRn (pr 0) FMOV.S @Rm+,FRn (sz 0) FMOV @Rm+,DRn (sz 1) FLOAT FPUL,DRn (pr 1) FLOAT FPUL,FRn (pr 0) FNEG DRn (pr 1) FNEG FRn (pr 0) FTRC DRm,FPUL (pr 1) FTRC FRm,FPUL (pr 0) FMOV.S @(R0,Rm),FRn (sz 0) FMOV @(R0,Rm),DRn (sz 1) FMOV.S @Rm,FRn (sz 0) FMOV @Rm,DRn (sz 1) FMOV XDm,XDn (sz 1) FMOV FRm,FRn (sz 0) FABS FRn (pr 0) FABS DRn (pr 1) FMOV.S FRm,@Rn (sz 0) FMOV DRm,@Rn (sz 1) FSUB DRm,DRn (pr 1) FSUB FRm,FRn (pr 0) FDIV DRm,DRn (pr 1) FDIV FRm,FRn (pr 0) FCMP/GT DRm,DRn (pr 1) FCMP/GT FRm,FRn (pr 0) FMOV DRm,DRn (sz 1) FMOV FRm,FRn (sz 0) FMOV.S FRm,@-Rn (sz 0) FMOV DRm,@-Rn (sz 1) FADD DRm,DRn (pr 1) FADD FRm,FRn (pr 0) FMOV.S FRm,@Rn (sz 0) FMOV XDm,@Rn (sz 1) FMOV.S @(R0,Rm),FRn (sz 0) FMOV @(R0,Rm),XDn (sz 1) FMOV DRm,XDn (sz 1) FMOV FRm,FRn (sz 0) FMOV XDm,@-Rn (sz 1) FMOV.S FRm,@-Rn (sz 0) FSQRT DRn (pr 1) FSQRT FRn (pr 0) FMOV.S @Rm,FRn (sz 0) FMOV @Rm,XDn (sz 1) This commit automatically calculates which FPU instructions require FPSCR-discrimination, and automatically inserts the appropriate conditional logic in the instruction decoder.
This commit is contained in:
parent
811c07f4ae
commit
eb43981b8b
11
c/Makefile
11
c/Makefile
@ -34,3 +34,14 @@ main: $(OBJS)
|
|||||||
$(CC) $^ -o $@
|
$(CC) $^ -o $@
|
||||||
|
|
||||||
-include $(shell find -type f -name '*.d')
|
-include $(shell find -type f -name '*.d')
|
||||||
|
|
||||||
|
.SUFFIXES:
|
||||||
|
.INTERMEDIATE:
|
||||||
|
.SECONDARY:
|
||||||
|
.PHONY: all clean
|
||||||
|
|
||||||
|
%: RCS/%,v
|
||||||
|
%: RCS/%
|
||||||
|
%: %,v
|
||||||
|
%: s.%
|
||||||
|
%: SCCS/s.%
|
||||||
|
@ -456,94 +456,120 @@ enum decode_status decode_and_execute_instruction(struct architectural_state * s
|
|||||||
}
|
}
|
||||||
case 0b1111000000000000: // FADD FRm,FRn
|
case 0b1111000000000000: // FADD FRm,FRn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
if (state->fpscr.bits.pr == 0) {
|
||||||
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
||||||
fadd__source_and_destination_operands(state, map, m, n);
|
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
||||||
return DECODE__DEFINED;
|
fadd__source_and_destination_operands(state, map, m, n);
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000000001: // FSUB FRm,FRn
|
case 0b1111000000000001: // FSUB FRm,FRn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
if (state->fpscr.bits.pr == 0) {
|
||||||
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
||||||
fsub__source_and_destination_operands(state, map, m, n);
|
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
||||||
return DECODE__DEFINED;
|
fsub__source_and_destination_operands(state, map, m, n);
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000000010: // FMUL FRm,FRn
|
case 0b1111000000000010: // FMUL FRm,FRn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
if (state->fpscr.bits.pr == 0) {
|
||||||
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
||||||
fmul__source_and_destination_operands(state, map, m, n);
|
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
||||||
return DECODE__DEFINED;
|
fmul__source_and_destination_operands(state, map, m, n);
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000000011: // FDIV FRm,FRn
|
case 0b1111000000000011: // FDIV FRm,FRn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
if (state->fpscr.bits.pr == 0) {
|
||||||
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
||||||
fdiv__source_and_destination_operands(state, map, m, n);
|
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
||||||
return DECODE__DEFINED;
|
fdiv__source_and_destination_operands(state, map, m, n);
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000000100: // FCMP/EQ FRm,FRn
|
case 0b1111000000000100: // FCMP/EQ FRm,FRn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
if (state->fpscr.bits.pr == 0) {
|
||||||
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
||||||
fcmp_eq__source_and_destination_operands(state, map, m, n);
|
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
||||||
return DECODE__DEFINED;
|
fcmp_eq__source_and_destination_operands(state, map, m, n);
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000000101: // FCMP/GT FRm,FRn
|
case 0b1111000000000101: // FCMP/GT FRm,FRn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
if (state->fpscr.bits.pr == 0) {
|
||||||
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
||||||
fcmp_gt__source_and_destination_operands(state, map, m, n);
|
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
||||||
return DECODE__DEFINED;
|
fcmp_gt__source_and_destination_operands(state, map, m, n);
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000000110: // FMOV.S @(R0,Rm),FRn
|
case 0b1111000000000110: // FMOV.S @(R0,Rm),FRn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
if (state->fpscr.bits.sz == 0) {
|
||||||
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
||||||
fmov_s__load_indexed_register_indirect(state, map, m, n);
|
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
||||||
return DECODE__DEFINED;
|
fmov_s__load_indexed_register_indirect(state, map, m, n);
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000000111: // FMOV.S FRm,@(R0,Rn)
|
case 0b1111000000000111: // FMOV.S FRm,@(R0,Rn)
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
if (state->fpscr.bits.sz == 0) {
|
||||||
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
||||||
fmov_s__store_indexed_register_indirect(state, map, m, n);
|
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
||||||
return DECODE__DEFINED;
|
fmov_s__store_indexed_register_indirect(state, map, m, n);
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000001000: // FMOV.S @Rm,FRn
|
case 0b1111000000001000: // FMOV.S @Rm,FRn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
if (state->fpscr.bits.sz == 0) {
|
||||||
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
||||||
fmov_s__load_register_direct_data_transfer(state, map, m, n);
|
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
||||||
return DECODE__DEFINED;
|
fmov_s__load_register_direct_data_transfer(state, map, m, n);
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000001001: // FMOV.S @Rm+,FRn
|
case 0b1111000000001001: // FMOV.S @Rm+,FRn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
if (state->fpscr.bits.sz == 0) {
|
||||||
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
||||||
fmov_s__load_direct_data_transfer_from_register(state, map, m, n);
|
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
||||||
return DECODE__DEFINED;
|
fmov_s__load_direct_data_transfer_from_register(state, map, m, n);
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000001010: // FMOV.S FRm,@Rn
|
case 0b1111000000001010: // FMOV.S FRm,@Rn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
if (state->fpscr.bits.sz == 0) {
|
||||||
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
||||||
fmov_s__store_register_direct_data_transfer(state, map, m, n);
|
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
||||||
return DECODE__DEFINED;
|
fmov_s__store_register_direct_data_transfer(state, map, m, n);
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000001011: // FMOV.S FRm,@-Rn
|
case 0b1111000000001011: // FMOV.S FRm,@-Rn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
if (state->fpscr.bits.sz == 0) {
|
||||||
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
||||||
fmov_s__store_direct_data_transfer_from_register(state, map, m, n);
|
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
||||||
return DECODE__DEFINED;
|
fmov_s__store_direct_data_transfer_from_register(state, map, m, n);
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000001100: // FMOV FRm,FRn
|
case 0b1111000000001100: // FMOV FRm,FRn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
if (state->fpscr.bits.sz == 0) {
|
||||||
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
||||||
fmov__source_and_destination_operands(state, map, m, n);
|
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
||||||
return DECODE__DEFINED;
|
fmov__source_and_destination_operands(state, map, m, n);
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000001110: // FMAC FR0,FRm,FRn
|
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
|
case 0b1111000000101101: // FLOAT FPUL,FRn
|
||||||
{
|
{
|
||||||
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
if (state->fpscr.bits.pr == 0) {
|
||||||
float__fpul_to_frn(state, map, n);
|
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
||||||
return DECODE__DEFINED;
|
float__fpul_to_frn(state, map, n);
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000111101: // FTRC FRm,FPUL
|
case 0b1111000000111101: // FTRC FRm,FPUL
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 8) & ((1 << 4) - 1);
|
if (state->fpscr.bits.pr == 0) {
|
||||||
ftrc__frm_to_fpul(state, map, m);
|
uint32_t m = (code >> 8) & ((1 << 4) - 1);
|
||||||
return DECODE__DEFINED;
|
ftrc__frm_to_fpul(state, map, m);
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000001001101: // FNEG FRn
|
case 0b1111000001001101: // FNEG FRn
|
||||||
{
|
{
|
||||||
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
if (state->fpscr.bits.pr == 0) {
|
||||||
fneg__destination_operand_only(state, map, n);
|
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
||||||
return DECODE__DEFINED;
|
fneg__destination_operand_only(state, map, n);
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000001011101: // FABS FRn
|
case 0b1111000001011101: // FABS FRn
|
||||||
{
|
{
|
||||||
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
if (state->fpscr.bits.pr == 0) {
|
||||||
fabs__destination_operand_only(state, map, n);
|
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
||||||
return DECODE__DEFINED;
|
fabs__destination_operand_only(state, map, n);
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000001101101: // FSQRT FRn
|
case 0b1111000001101101: // FSQRT FRn
|
||||||
{
|
{
|
||||||
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
if (state->fpscr.bits.pr == 0) {
|
||||||
fsqrt__destination_operand_only(state, map, n);
|
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
||||||
return DECODE__DEFINED;
|
fsqrt__destination_operand_only(state, map, n);
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000010001101: // FLDI0 FRn
|
case 0b1111000010001101: // FLDI0 FRn
|
||||||
{
|
{
|
||||||
@ -1274,193 +1310,247 @@ enum decode_status decode_and_execute_instruction(struct architectural_state * s
|
|||||||
switch (code & 0b1111000100011111) {
|
switch (code & 0b1111000100011111) {
|
||||||
case 0b1111000000000000: // FADD DRm,DRn
|
case 0b1111000000000000: // FADD DRm,DRn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
if (state->fpscr.bits.pr == 1) {
|
||||||
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
||||||
fadd__source_and_destination_operands_double(state, map, m, n);
|
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
||||||
return DECODE__DEFINED;
|
fadd__source_and_destination_operands_double(state, map, m, n);
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000000001: // FSUB DRm,DRn
|
case 0b1111000000000001: // FSUB DRm,DRn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
if (state->fpscr.bits.pr == 1) {
|
||||||
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
||||||
fsub__source_and_destination_operands_double(state, map, m, n);
|
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
||||||
return DECODE__DEFINED;
|
fsub__source_and_destination_operands_double(state, map, m, n);
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000000010: // FMUL DRm,DRn
|
case 0b1111000000000010: // FMUL DRm,DRn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
if (state->fpscr.bits.pr == 1) {
|
||||||
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
||||||
fmul__source_and_destination_operands_double(state, map, m, n);
|
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
||||||
return DECODE__DEFINED;
|
fmul__source_and_destination_operands_double(state, map, m, n);
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000000011: // FDIV DRm,DRn
|
case 0b1111000000000011: // FDIV DRm,DRn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
if (state->fpscr.bits.pr == 1) {
|
||||||
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
||||||
fdiv__source_and_destination_operands_double(state, map, m, n);
|
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
||||||
return DECODE__DEFINED;
|
fdiv__source_and_destination_operands_double(state, map, m, n);
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000000100: // FCMP/EQ DRm,DRn
|
case 0b1111000000000100: // FCMP/EQ DRm,DRn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
if (state->fpscr.bits.pr == 1) {
|
||||||
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
||||||
fcmp_eq__source_and_destination_operands_double(state, map, m, n);
|
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
||||||
return DECODE__DEFINED;
|
fcmp_eq__source_and_destination_operands_double(state, map, m, n);
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000000101: // FCMP/GT DRm,DRn
|
case 0b1111000000000101: // FCMP/GT DRm,DRn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
if (state->fpscr.bits.pr == 1) {
|
||||||
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
||||||
fcmp_gt__source_and_destination_operands_double(state, map, m, n);
|
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
||||||
return DECODE__DEFINED;
|
fcmp_gt__source_and_destination_operands_double(state, map, m, n);
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000001100: // FMOV DRm,DRn
|
case 0b1111000000001100: // FMOV DRm,DRn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
if (state->fpscr.bits.sz == 1) {
|
||||||
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
||||||
fmov__source_and_destination_operands_double(state, map, m, n);
|
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
||||||
return DECODE__DEFINED;
|
fmov__source_and_destination_operands_double(state, map, m, n);
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000011100: // FMOV XDm,DRn
|
case 0b1111000000011100: // FMOV XDm,DRn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
if (state->fpscr.bits.sz == 1) {
|
||||||
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
||||||
fmov__bank_to_double(state, map, m, n);
|
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
||||||
return DECODE__DEFINED;
|
fmov__bank_to_double(state, map, m, n);
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000100001100: // FMOV DRm,XDn
|
case 0b1111000100001100: // FMOV DRm,XDn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
if (state->fpscr.bits.sz == 1) {
|
||||||
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
||||||
fmov__double_to_bank(state, map, m, n);
|
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
||||||
return DECODE__DEFINED;
|
fmov__double_to_bank(state, map, m, n);
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000100011100: // FMOV XDm,XDn
|
case 0b1111000100011100: // FMOV XDm,XDn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
if (state->fpscr.bits.sz == 1) {
|
||||||
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
||||||
fmov__source_and_destination_operands_bank(state, map, m, n);
|
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
||||||
return DECODE__DEFINED;
|
fmov__source_and_destination_operands_bank(state, map, m, n);
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch (code & 0b1111000100001111) {
|
switch (code & 0b1111000100001111) {
|
||||||
case 0b1111000000000110: // FMOV @(R0,Rm),DRn
|
case 0b1111000000000110: // FMOV @(R0,Rm),DRn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
if (state->fpscr.bits.sz == 1) {
|
||||||
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
||||||
fmov__load_indexed_register_indirect_double(state, map, m, n);
|
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
||||||
return DECODE__DEFINED;
|
fmov__load_indexed_register_indirect_double(state, map, m, n);
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000001000: // FMOV @Rm,DRn
|
case 0b1111000000001000: // FMOV @Rm,DRn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
if (state->fpscr.bits.sz == 1) {
|
||||||
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
||||||
fmov__load_register_direct_data_transfer_double(state, map, m, n);
|
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
||||||
return DECODE__DEFINED;
|
fmov__load_register_direct_data_transfer_double(state, map, m, n);
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000001001: // FMOV @Rm+,DRn
|
case 0b1111000000001001: // FMOV @Rm+,DRn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
if (state->fpscr.bits.sz == 1) {
|
||||||
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
||||||
fmov__load_direct_data_transfer_from_register_double(state, map, m, n);
|
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
||||||
return DECODE__DEFINED;
|
fmov__load_direct_data_transfer_from_register_double(state, map, m, n);
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000100000110: // FMOV @(R0,Rm),XDn
|
case 0b1111000100000110: // FMOV @(R0,Rm),XDn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
if (state->fpscr.bits.sz == 1) {
|
||||||
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
||||||
fmov__load_indexed_register_indirect_bank(state, map, m, n);
|
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
||||||
return DECODE__DEFINED;
|
fmov__load_indexed_register_indirect_bank(state, map, m, n);
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000100001000: // FMOV @Rm,XDn
|
case 0b1111000100001000: // FMOV @Rm,XDn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
if (state->fpscr.bits.sz == 1) {
|
||||||
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
||||||
fmov__load_register_direct_data_transfer_bank(state, map, m, n);
|
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
||||||
return DECODE__DEFINED;
|
fmov__load_register_direct_data_transfer_bank(state, map, m, n);
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000100001001: // FMOV @Rm+,XDn
|
case 0b1111000100001001: // FMOV @Rm+,XDn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
if (state->fpscr.bits.sz == 1) {
|
||||||
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
||||||
fmov__load_direct_data_transfer_from_register_bank(state, map, m, n);
|
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
||||||
return DECODE__DEFINED;
|
fmov__load_direct_data_transfer_from_register_bank(state, map, m, n);
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch (code & 0b1111000000011111) {
|
switch (code & 0b1111000000011111) {
|
||||||
case 0b1111000000000111: // FMOV DRm,@(R0,Rn)
|
case 0b1111000000000111: // FMOV DRm,@(R0,Rn)
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
if (state->fpscr.bits.sz == 1) {
|
||||||
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
||||||
fmov__store_indexed_register_indirect_double(state, map, m, n);
|
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
||||||
return DECODE__DEFINED;
|
fmov__store_indexed_register_indirect_double(state, map, m, n);
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000001010: // FMOV DRm,@Rn
|
case 0b1111000000001010: // FMOV DRm,@Rn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
if (state->fpscr.bits.sz == 1) {
|
||||||
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
||||||
fmov__store_register_direct_data_transfer_double(state, map, m, n);
|
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
||||||
return DECODE__DEFINED;
|
fmov__store_register_direct_data_transfer_double(state, map, m, n);
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000001011: // FMOV DRm,@-Rn
|
case 0b1111000000001011: // FMOV DRm,@-Rn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
if (state->fpscr.bits.sz == 1) {
|
||||||
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
||||||
fmov__store_direct_data_transfer_from_register_double(state, map, m, n);
|
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
||||||
return DECODE__DEFINED;
|
fmov__store_direct_data_transfer_from_register_double(state, map, m, n);
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000010111: // FMOV XDm,@(R0,Rn)
|
case 0b1111000000010111: // FMOV XDm,@(R0,Rn)
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
if (state->fpscr.bits.sz == 1) {
|
||||||
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
||||||
fmov__store_indexed_register_indirect_bank(state, map, m, n);
|
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
||||||
return DECODE__DEFINED;
|
fmov__store_indexed_register_indirect_bank(state, map, m, n);
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000011010: // FMOV XDm,@Rn
|
case 0b1111000000011010: // FMOV XDm,@Rn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
if (state->fpscr.bits.sz == 1) {
|
||||||
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
||||||
fmov__store_register_direct_data_transfer_bank(state, map, m, n);
|
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
||||||
return DECODE__DEFINED;
|
fmov__store_register_direct_data_transfer_bank(state, map, m, n);
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000011011: // FMOV XDm,@-Rn
|
case 0b1111000000011011: // FMOV XDm,@-Rn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
if (state->fpscr.bits.sz == 1) {
|
||||||
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
||||||
fmov__store_direct_data_transfer_from_register_bank(state, map, m, n);
|
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
||||||
return DECODE__DEFINED;
|
fmov__store_direct_data_transfer_from_register_bank(state, map, m, n);
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch (code & 0b1111000111111111) {
|
switch (code & 0b1111000111111111) {
|
||||||
case 0b1111000000101101: // FLOAT FPUL,DRn
|
case 0b1111000000101101: // FLOAT FPUL,DRn
|
||||||
{
|
{
|
||||||
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
if (state->fpscr.bits.pr == 1) {
|
||||||
float__fpul_to_drn(state, map, n);
|
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
||||||
return DECODE__DEFINED;
|
float__fpul_to_drn(state, map, n);
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000111101: // FTRC DRm,FPUL
|
case 0b1111000000111101: // FTRC DRm,FPUL
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 9) & ((1 << 3) - 1);
|
if (state->fpscr.bits.pr == 1) {
|
||||||
ftrc__drm_to_fpul(state, map, m);
|
uint32_t m = (code >> 9) & ((1 << 3) - 1);
|
||||||
return DECODE__DEFINED;
|
ftrc__drm_to_fpul(state, map, m);
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000001001101: // FNEG DRn
|
case 0b1111000001001101: // FNEG DRn
|
||||||
{
|
{
|
||||||
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
if (state->fpscr.bits.pr == 1) {
|
||||||
fneg__destination_operand_only_double(state, map, n);
|
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
||||||
return DECODE__DEFINED;
|
fneg__destination_operand_only_double(state, map, n);
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000001011101: // FABS DRn
|
case 0b1111000001011101: // FABS DRn
|
||||||
{
|
{
|
||||||
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
if (state->fpscr.bits.pr == 1) {
|
||||||
fabs__destination_operand_only_double(state, map, n);
|
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
||||||
return DECODE__DEFINED;
|
fabs__destination_operand_only_double(state, map, n);
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000001101101: // FSQRT DRn
|
case 0b1111000001101101: // FSQRT DRn
|
||||||
{
|
{
|
||||||
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
if (state->fpscr.bits.pr == 1) {
|
||||||
fsqrt__destination_operand_only_double(state, map, n);
|
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
||||||
return DECODE__DEFINED;
|
fsqrt__destination_operand_only_double(state, map, n);
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000010101101: // FCNVSD FPUL,DRn
|
case 0b1111000010101101: // FCNVSD FPUL,DRn
|
||||||
{
|
{
|
||||||
|
520
c/decode_print.c
520
c/decode_print.c
@ -521,107 +521,133 @@ enum decode_status decode_and_print_instruction(struct architectural_state * sta
|
|||||||
}
|
}
|
||||||
case 0b1111000000000000: // FADD FRm,FRn
|
case 0b1111000000000000: // FADD FRm,FRn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
if (state->fpscr.bits.pr == 0) {
|
||||||
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
||||||
snprintf(operand_buf, size, "FR%d,FR%d", m, n);
|
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
||||||
*instruction_buf = "FADD";
|
snprintf(operand_buf, size, "FR%d,FR%d", m, n);
|
||||||
return DECODE__DEFINED;
|
*instruction_buf = "FADD";
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000000001: // FSUB FRm,FRn
|
case 0b1111000000000001: // FSUB FRm,FRn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
if (state->fpscr.bits.pr == 0) {
|
||||||
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
||||||
snprintf(operand_buf, size, "FR%d,FR%d", m, n);
|
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
||||||
*instruction_buf = "FSUB";
|
snprintf(operand_buf, size, "FR%d,FR%d", m, n);
|
||||||
return DECODE__DEFINED;
|
*instruction_buf = "FSUB";
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000000010: // FMUL FRm,FRn
|
case 0b1111000000000010: // FMUL FRm,FRn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
if (state->fpscr.bits.pr == 0) {
|
||||||
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
||||||
snprintf(operand_buf, size, "FR%d,FR%d", m, n);
|
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
||||||
*instruction_buf = "FMUL";
|
snprintf(operand_buf, size, "FR%d,FR%d", m, n);
|
||||||
return DECODE__DEFINED;
|
*instruction_buf = "FMUL";
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000000011: // FDIV FRm,FRn
|
case 0b1111000000000011: // FDIV FRm,FRn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
if (state->fpscr.bits.pr == 0) {
|
||||||
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
||||||
snprintf(operand_buf, size, "FR%d,FR%d", m, n);
|
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
||||||
*instruction_buf = "FDIV";
|
snprintf(operand_buf, size, "FR%d,FR%d", m, n);
|
||||||
return DECODE__DEFINED;
|
*instruction_buf = "FDIV";
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000000100: // FCMP/EQ FRm,FRn
|
case 0b1111000000000100: // FCMP/EQ FRm,FRn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
if (state->fpscr.bits.pr == 0) {
|
||||||
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
||||||
snprintf(operand_buf, size, "FR%d,FR%d", m, n);
|
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
||||||
*instruction_buf = "FCMP/EQ";
|
snprintf(operand_buf, size, "FR%d,FR%d", m, n);
|
||||||
return DECODE__DEFINED;
|
*instruction_buf = "FCMP/EQ";
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000000101: // FCMP/GT FRm,FRn
|
case 0b1111000000000101: // FCMP/GT FRm,FRn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
if (state->fpscr.bits.pr == 0) {
|
||||||
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
||||||
snprintf(operand_buf, size, "FR%d,FR%d", m, n);
|
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
||||||
*instruction_buf = "FCMP/GT";
|
snprintf(operand_buf, size, "FR%d,FR%d", m, n);
|
||||||
return DECODE__DEFINED;
|
*instruction_buf = "FCMP/GT";
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000000110: // FMOV.S @(R0,Rm),FRn
|
case 0b1111000000000110: // FMOV.S @(R0,Rm),FRn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
if (state->fpscr.bits.sz == 0) {
|
||||||
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
||||||
snprintf(operand_buf, size, "@(R0,R%d),FR%d", m, n);
|
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
||||||
*instruction_buf = "FMOV.S";
|
snprintf(operand_buf, size, "@(R0,R%d),FR%d", m, n);
|
||||||
return DECODE__DEFINED;
|
*instruction_buf = "FMOV.S";
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000000111: // FMOV.S FRm,@(R0,Rn)
|
case 0b1111000000000111: // FMOV.S FRm,@(R0,Rn)
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
if (state->fpscr.bits.sz == 0) {
|
||||||
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
||||||
snprintf(operand_buf, size, "FR%d,@(R0,R%d)", m, n);
|
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
||||||
*instruction_buf = "FMOV.S";
|
snprintf(operand_buf, size, "FR%d,@(R0,R%d)", m, n);
|
||||||
return DECODE__DEFINED;
|
*instruction_buf = "FMOV.S";
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000001000: // FMOV.S @Rm,FRn
|
case 0b1111000000001000: // FMOV.S @Rm,FRn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
if (state->fpscr.bits.sz == 0) {
|
||||||
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
||||||
snprintf(operand_buf, size, "@R%d,FR%d", m, n);
|
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
||||||
*instruction_buf = "FMOV.S";
|
snprintf(operand_buf, size, "@R%d,FR%d", m, n);
|
||||||
return DECODE__DEFINED;
|
*instruction_buf = "FMOV.S";
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000001001: // FMOV.S @Rm+,FRn
|
case 0b1111000000001001: // FMOV.S @Rm+,FRn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
if (state->fpscr.bits.sz == 0) {
|
||||||
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
||||||
snprintf(operand_buf, size, "@R%d+,FR%d", m, n);
|
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
||||||
*instruction_buf = "FMOV.S";
|
snprintf(operand_buf, size, "@R%d+,FR%d", m, n);
|
||||||
return DECODE__DEFINED;
|
*instruction_buf = "FMOV.S";
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000001010: // FMOV.S FRm,@Rn
|
case 0b1111000000001010: // FMOV.S FRm,@Rn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
if (state->fpscr.bits.sz == 0) {
|
||||||
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
||||||
snprintf(operand_buf, size, "FR%d,@R%d", m, n);
|
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
||||||
*instruction_buf = "FMOV.S";
|
snprintf(operand_buf, size, "FR%d,@R%d", m, n);
|
||||||
return DECODE__DEFINED;
|
*instruction_buf = "FMOV.S";
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000001011: // FMOV.S FRm,@-Rn
|
case 0b1111000000001011: // FMOV.S FRm,@-Rn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
if (state->fpscr.bits.sz == 0) {
|
||||||
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
||||||
snprintf(operand_buf, size, "FR%d,@-R%d", m, n);
|
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
||||||
*instruction_buf = "FMOV.S";
|
snprintf(operand_buf, size, "FR%d,@-R%d", m, n);
|
||||||
return DECODE__DEFINED;
|
*instruction_buf = "FMOV.S";
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000001100: // FMOV FRm,FRn
|
case 0b1111000000001100: // FMOV FRm,FRn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
if (state->fpscr.bits.sz == 0) {
|
||||||
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
||||||
snprintf(operand_buf, size, "FR%d,FR%d", m, n);
|
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
||||||
*instruction_buf = "FMOV";
|
snprintf(operand_buf, size, "FR%d,FR%d", m, n);
|
||||||
return DECODE__DEFINED;
|
*instruction_buf = "FMOV";
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000001110: // FMAC FR0,FRm,FRn
|
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
|
case 0b1111000000101101: // FLOAT FPUL,FRn
|
||||||
{
|
{
|
||||||
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
if (state->fpscr.bits.pr == 0) {
|
||||||
snprintf(operand_buf, size, "FPUL,FR%d", n);
|
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
||||||
*instruction_buf = "FLOAT";
|
snprintf(operand_buf, size, "FPUL,FR%d", n);
|
||||||
return DECODE__DEFINED;
|
*instruction_buf = "FLOAT";
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000111101: // FTRC FRm,FPUL
|
case 0b1111000000111101: // FTRC FRm,FPUL
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 8) & ((1 << 4) - 1);
|
if (state->fpscr.bits.pr == 0) {
|
||||||
snprintf(operand_buf, size, "FR%d,FPUL", m);
|
uint32_t m = (code >> 8) & ((1 << 4) - 1);
|
||||||
*instruction_buf = "FTRC";
|
snprintf(operand_buf, size, "FR%d,FPUL", m);
|
||||||
return DECODE__DEFINED;
|
*instruction_buf = "FTRC";
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000001001101: // FNEG FRn
|
case 0b1111000001001101: // FNEG FRn
|
||||||
{
|
{
|
||||||
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
if (state->fpscr.bits.pr == 0) {
|
||||||
snprintf(operand_buf, size, "FR%d", n);
|
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
||||||
*instruction_buf = "FNEG";
|
snprintf(operand_buf, size, "FR%d", n);
|
||||||
return DECODE__DEFINED;
|
*instruction_buf = "FNEG";
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000001011101: // FABS FRn
|
case 0b1111000001011101: // FABS FRn
|
||||||
{
|
{
|
||||||
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
if (state->fpscr.bits.pr == 0) {
|
||||||
snprintf(operand_buf, size, "FR%d", n);
|
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
||||||
*instruction_buf = "FABS";
|
snprintf(operand_buf, size, "FR%d", n);
|
||||||
return DECODE__DEFINED;
|
*instruction_buf = "FABS";
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000001101101: // FSQRT FRn
|
case 0b1111000001101101: // FSQRT FRn
|
||||||
{
|
{
|
||||||
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
if (state->fpscr.bits.pr == 0) {
|
||||||
snprintf(operand_buf, size, "FR%d", n);
|
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
||||||
*instruction_buf = "FSQRT";
|
snprintf(operand_buf, size, "FR%d", n);
|
||||||
return DECODE__DEFINED;
|
*instruction_buf = "FSQRT";
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000010001101: // FLDI0 FRn
|
case 0b1111000010001101: // FLDI0 FRn
|
||||||
{
|
{
|
||||||
@ -1472,220 +1508,274 @@ enum decode_status decode_and_print_instruction(struct architectural_state * sta
|
|||||||
switch (code & 0b1111000100011111) {
|
switch (code & 0b1111000100011111) {
|
||||||
case 0b1111000000000000: // FADD DRm,DRn
|
case 0b1111000000000000: // FADD DRm,DRn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
if (state->fpscr.bits.pr == 1) {
|
||||||
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
||||||
snprintf(operand_buf, size, "DR%d,DR%d", m, n);
|
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
||||||
*instruction_buf = "FADD";
|
snprintf(operand_buf, size, "DR%d,DR%d", m, n);
|
||||||
return DECODE__DEFINED;
|
*instruction_buf = "FADD";
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000000001: // FSUB DRm,DRn
|
case 0b1111000000000001: // FSUB DRm,DRn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
if (state->fpscr.bits.pr == 1) {
|
||||||
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
||||||
snprintf(operand_buf, size, "DR%d,DR%d", m, n);
|
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
||||||
*instruction_buf = "FSUB";
|
snprintf(operand_buf, size, "DR%d,DR%d", m, n);
|
||||||
return DECODE__DEFINED;
|
*instruction_buf = "FSUB";
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000000010: // FMUL DRm,DRn
|
case 0b1111000000000010: // FMUL DRm,DRn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
if (state->fpscr.bits.pr == 1) {
|
||||||
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
||||||
snprintf(operand_buf, size, "DR%d,DR%d", m, n);
|
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
||||||
*instruction_buf = "FMUL";
|
snprintf(operand_buf, size, "DR%d,DR%d", m, n);
|
||||||
return DECODE__DEFINED;
|
*instruction_buf = "FMUL";
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000000011: // FDIV DRm,DRn
|
case 0b1111000000000011: // FDIV DRm,DRn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
if (state->fpscr.bits.pr == 1) {
|
||||||
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
||||||
snprintf(operand_buf, size, "DR%d,DR%d", m, n);
|
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
||||||
*instruction_buf = "FDIV";
|
snprintf(operand_buf, size, "DR%d,DR%d", m, n);
|
||||||
return DECODE__DEFINED;
|
*instruction_buf = "FDIV";
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000000100: // FCMP/EQ DRm,DRn
|
case 0b1111000000000100: // FCMP/EQ DRm,DRn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
if (state->fpscr.bits.pr == 1) {
|
||||||
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
||||||
snprintf(operand_buf, size, "DR%d,DR%d", m, n);
|
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
||||||
*instruction_buf = "FCMP/EQ";
|
snprintf(operand_buf, size, "DR%d,DR%d", m, n);
|
||||||
return DECODE__DEFINED;
|
*instruction_buf = "FCMP/EQ";
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000000101: // FCMP/GT DRm,DRn
|
case 0b1111000000000101: // FCMP/GT DRm,DRn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
if (state->fpscr.bits.pr == 1) {
|
||||||
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
||||||
snprintf(operand_buf, size, "DR%d,DR%d", m, n);
|
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
||||||
*instruction_buf = "FCMP/GT";
|
snprintf(operand_buf, size, "DR%d,DR%d", m, n);
|
||||||
return DECODE__DEFINED;
|
*instruction_buf = "FCMP/GT";
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000001100: // FMOV DRm,DRn
|
case 0b1111000000001100: // FMOV DRm,DRn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
if (state->fpscr.bits.sz == 1) {
|
||||||
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
||||||
snprintf(operand_buf, size, "DR%d,DR%d", m, n);
|
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
||||||
*instruction_buf = "FMOV";
|
snprintf(operand_buf, size, "DR%d,DR%d", m, n);
|
||||||
return DECODE__DEFINED;
|
*instruction_buf = "FMOV";
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000011100: // FMOV XDm,DRn
|
case 0b1111000000011100: // FMOV XDm,DRn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
if (state->fpscr.bits.sz == 1) {
|
||||||
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
||||||
snprintf(operand_buf, size, "XD%d,DR%d", m, n);
|
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
||||||
*instruction_buf = "FMOV";
|
snprintf(operand_buf, size, "XD%d,DR%d", m, n);
|
||||||
return DECODE__DEFINED;
|
*instruction_buf = "FMOV";
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000100001100: // FMOV DRm,XDn
|
case 0b1111000100001100: // FMOV DRm,XDn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
if (state->fpscr.bits.sz == 1) {
|
||||||
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
||||||
snprintf(operand_buf, size, "DR%d,XD%d", m, n);
|
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
||||||
*instruction_buf = "FMOV";
|
snprintf(operand_buf, size, "DR%d,XD%d", m, n);
|
||||||
return DECODE__DEFINED;
|
*instruction_buf = "FMOV";
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000100011100: // FMOV XDm,XDn
|
case 0b1111000100011100: // FMOV XDm,XDn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
if (state->fpscr.bits.sz == 1) {
|
||||||
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
||||||
snprintf(operand_buf, size, "XD%d,XD%d", m, n);
|
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
||||||
*instruction_buf = "FMOV";
|
snprintf(operand_buf, size, "XD%d,XD%d", m, n);
|
||||||
return DECODE__DEFINED;
|
*instruction_buf = "FMOV";
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch (code & 0b1111000100001111) {
|
switch (code & 0b1111000100001111) {
|
||||||
case 0b1111000000000110: // FMOV @(R0,Rm),DRn
|
case 0b1111000000000110: // FMOV @(R0,Rm),DRn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
if (state->fpscr.bits.sz == 1) {
|
||||||
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
||||||
snprintf(operand_buf, size, "@(R0,R%d),DR%d", m, n);
|
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
||||||
*instruction_buf = "FMOV";
|
snprintf(operand_buf, size, "@(R0,R%d),DR%d", m, n);
|
||||||
return DECODE__DEFINED;
|
*instruction_buf = "FMOV";
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000001000: // FMOV @Rm,DRn
|
case 0b1111000000001000: // FMOV @Rm,DRn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
if (state->fpscr.bits.sz == 1) {
|
||||||
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
||||||
snprintf(operand_buf, size, "@R%d,DR%d", m, n);
|
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
||||||
*instruction_buf = "FMOV";
|
snprintf(operand_buf, size, "@R%d,DR%d", m, n);
|
||||||
return DECODE__DEFINED;
|
*instruction_buf = "FMOV";
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000001001: // FMOV @Rm+,DRn
|
case 0b1111000000001001: // FMOV @Rm+,DRn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
if (state->fpscr.bits.sz == 1) {
|
||||||
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
||||||
snprintf(operand_buf, size, "@R%d+,DR%d", m, n);
|
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
||||||
*instruction_buf = "FMOV";
|
snprintf(operand_buf, size, "@R%d+,DR%d", m, n);
|
||||||
return DECODE__DEFINED;
|
*instruction_buf = "FMOV";
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000100000110: // FMOV @(R0,Rm),XDn
|
case 0b1111000100000110: // FMOV @(R0,Rm),XDn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
if (state->fpscr.bits.sz == 1) {
|
||||||
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
||||||
snprintf(operand_buf, size, "@(R0,R%d),XD%d", m, n);
|
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
||||||
*instruction_buf = "FMOV";
|
snprintf(operand_buf, size, "@(R0,R%d),XD%d", m, n);
|
||||||
return DECODE__DEFINED;
|
*instruction_buf = "FMOV";
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000100001000: // FMOV @Rm,XDn
|
case 0b1111000100001000: // FMOV @Rm,XDn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
if (state->fpscr.bits.sz == 1) {
|
||||||
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
||||||
snprintf(operand_buf, size, "@R%d,XD%d", m, n);
|
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
||||||
*instruction_buf = "FMOV";
|
snprintf(operand_buf, size, "@R%d,XD%d", m, n);
|
||||||
return DECODE__DEFINED;
|
*instruction_buf = "FMOV";
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000100001001: // FMOV @Rm+,XDn
|
case 0b1111000100001001: // FMOV @Rm+,XDn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
if (state->fpscr.bits.sz == 1) {
|
||||||
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
uint32_t m = (code >> 4) & ((1 << 4) - 1);
|
||||||
snprintf(operand_buf, size, "@R%d+,XD%d", m, n);
|
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
||||||
*instruction_buf = "FMOV";
|
snprintf(operand_buf, size, "@R%d+,XD%d", m, n);
|
||||||
return DECODE__DEFINED;
|
*instruction_buf = "FMOV";
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch (code & 0b1111000000011111) {
|
switch (code & 0b1111000000011111) {
|
||||||
case 0b1111000000000111: // FMOV DRm,@(R0,Rn)
|
case 0b1111000000000111: // FMOV DRm,@(R0,Rn)
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
if (state->fpscr.bits.sz == 1) {
|
||||||
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
||||||
snprintf(operand_buf, size, "DR%d,@(R0,R%d)", m, n);
|
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
||||||
*instruction_buf = "FMOV";
|
snprintf(operand_buf, size, "DR%d,@(R0,R%d)", m, n);
|
||||||
return DECODE__DEFINED;
|
*instruction_buf = "FMOV";
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000001010: // FMOV DRm,@Rn
|
case 0b1111000000001010: // FMOV DRm,@Rn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
if (state->fpscr.bits.sz == 1) {
|
||||||
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
||||||
snprintf(operand_buf, size, "DR%d,@R%d", m, n);
|
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
||||||
*instruction_buf = "FMOV";
|
snprintf(operand_buf, size, "DR%d,@R%d", m, n);
|
||||||
return DECODE__DEFINED;
|
*instruction_buf = "FMOV";
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000001011: // FMOV DRm,@-Rn
|
case 0b1111000000001011: // FMOV DRm,@-Rn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
if (state->fpscr.bits.sz == 1) {
|
||||||
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
||||||
snprintf(operand_buf, size, "DR%d,@-R%d", m, n);
|
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
||||||
*instruction_buf = "FMOV";
|
snprintf(operand_buf, size, "DR%d,@-R%d", m, n);
|
||||||
return DECODE__DEFINED;
|
*instruction_buf = "FMOV";
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000010111: // FMOV XDm,@(R0,Rn)
|
case 0b1111000000010111: // FMOV XDm,@(R0,Rn)
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
if (state->fpscr.bits.sz == 1) {
|
||||||
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
||||||
snprintf(operand_buf, size, "XD%d,@(R0,R%d)", m, n);
|
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
||||||
*instruction_buf = "FMOV";
|
snprintf(operand_buf, size, "XD%d,@(R0,R%d)", m, n);
|
||||||
return DECODE__DEFINED;
|
*instruction_buf = "FMOV";
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000011010: // FMOV XDm,@Rn
|
case 0b1111000000011010: // FMOV XDm,@Rn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
if (state->fpscr.bits.sz == 1) {
|
||||||
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
||||||
snprintf(operand_buf, size, "XD%d,@R%d", m, n);
|
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
||||||
*instruction_buf = "FMOV";
|
snprintf(operand_buf, size, "XD%d,@R%d", m, n);
|
||||||
return DECODE__DEFINED;
|
*instruction_buf = "FMOV";
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000011011: // FMOV XDm,@-Rn
|
case 0b1111000000011011: // FMOV XDm,@-Rn
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
if (state->fpscr.bits.sz == 1) {
|
||||||
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
uint32_t m = (code >> 5) & ((1 << 3) - 1);
|
||||||
snprintf(operand_buf, size, "XD%d,@-R%d", m, n);
|
uint32_t n = (code >> 8) & ((1 << 4) - 1);
|
||||||
*instruction_buf = "FMOV";
|
snprintf(operand_buf, size, "XD%d,@-R%d", m, n);
|
||||||
return DECODE__DEFINED;
|
*instruction_buf = "FMOV";
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch (code & 0b1111000111111111) {
|
switch (code & 0b1111000111111111) {
|
||||||
case 0b1111000000101101: // FLOAT FPUL,DRn
|
case 0b1111000000101101: // FLOAT FPUL,DRn
|
||||||
{
|
{
|
||||||
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
if (state->fpscr.bits.pr == 1) {
|
||||||
snprintf(operand_buf, size, "FPUL,DR%d", n);
|
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
||||||
*instruction_buf = "FLOAT";
|
snprintf(operand_buf, size, "FPUL,DR%d", n);
|
||||||
return DECODE__DEFINED;
|
*instruction_buf = "FLOAT";
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000000111101: // FTRC DRm,FPUL
|
case 0b1111000000111101: // FTRC DRm,FPUL
|
||||||
{
|
{
|
||||||
uint32_t m = (code >> 9) & ((1 << 3) - 1);
|
if (state->fpscr.bits.pr == 1) {
|
||||||
snprintf(operand_buf, size, "DR%d,FPUL", m);
|
uint32_t m = (code >> 9) & ((1 << 3) - 1);
|
||||||
*instruction_buf = "FTRC";
|
snprintf(operand_buf, size, "DR%d,FPUL", m);
|
||||||
return DECODE__DEFINED;
|
*instruction_buf = "FTRC";
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000001001101: // FNEG DRn
|
case 0b1111000001001101: // FNEG DRn
|
||||||
{
|
{
|
||||||
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
if (state->fpscr.bits.pr == 1) {
|
||||||
snprintf(operand_buf, size, "DR%d", n);
|
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
||||||
*instruction_buf = "FNEG";
|
snprintf(operand_buf, size, "DR%d", n);
|
||||||
return DECODE__DEFINED;
|
*instruction_buf = "FNEG";
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000001011101: // FABS DRn
|
case 0b1111000001011101: // FABS DRn
|
||||||
{
|
{
|
||||||
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
if (state->fpscr.bits.pr == 1) {
|
||||||
snprintf(operand_buf, size, "DR%d", n);
|
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
||||||
*instruction_buf = "FABS";
|
snprintf(operand_buf, size, "DR%d", n);
|
||||||
return DECODE__DEFINED;
|
*instruction_buf = "FABS";
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000001101101: // FSQRT DRn
|
case 0b1111000001101101: // FSQRT DRn
|
||||||
{
|
{
|
||||||
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
if (state->fpscr.bits.pr == 1) {
|
||||||
snprintf(operand_buf, size, "DR%d", n);
|
uint32_t n = (code >> 9) & ((1 << 3) - 1);
|
||||||
*instruction_buf = "FSQRT";
|
snprintf(operand_buf, size, "DR%d", n);
|
||||||
return DECODE__DEFINED;
|
*instruction_buf = "FSQRT";
|
||||||
|
return DECODE__DEFINED;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
case 0b1111000010101101: // FCNVSD FPUL,DRn
|
case 0b1111000010101101: // FCNVSD FPUL,DRn
|
||||||
{
|
{
|
||||||
|
@ -5,6 +5,8 @@ from instruction_table import untabulate_instructions_sh4
|
|||||||
from instruction_table import untabulate_instructions_sh2
|
from instruction_table import untabulate_instructions_sh2
|
||||||
from instruction_function_name import instruction_function_name
|
from instruction_function_name import instruction_function_name
|
||||||
from generate import renderer
|
from generate import renderer
|
||||||
|
from generate_impl import parse_header
|
||||||
|
from generate_impl import read_ins_source
|
||||||
|
|
||||||
from disabled_instructions import disabled_instructions
|
from disabled_instructions import disabled_instructions
|
||||||
|
|
||||||
@ -41,34 +43,39 @@ def render_execute(ins):
|
|||||||
variable_args = ", " + ", ".join(ins.variables) if ins.variables else ""
|
variable_args = ", " + ", ".join(ins.variables) if ins.variables else ""
|
||||||
yield f"{function_name}(state, map{variable_args});"
|
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)}) {{"
|
yield f"switch (code & {b16(mask)}) {{"
|
||||||
for ins in instructions:
|
for ins in instructions:
|
||||||
yield f"case {b16(ins.code.code_bits)}: // {ins.instruction} {ins.operands}"
|
yield f"case {b16(ins.code.code_bits)}: // {ins.instruction} {ins.operands}"
|
||||||
yield "{"
|
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:
|
for variable in ins.variables:
|
||||||
operand_var = ins.code.operands[variable]
|
operand_var = ins.code.operands[variable]
|
||||||
yield f"uint32_t {variable} = (code >> {operand_var.lsb}) & ((1 << {operand_var.length}) - 1);"
|
yield f"uint32_t {variable} = (code >> {operand_var.lsb}) & ((1 << {operand_var.length}) - 1);"
|
||||||
yield from body_func(ins)
|
yield from body_func(ins)
|
||||||
yield f"return DECODE__DEFINED;"
|
yield f"return DECODE__DEFINED;"
|
||||||
|
if (ins.instruction, ins.operands) in discriminators:
|
||||||
|
yield "} else break;"
|
||||||
yield "}"
|
yield "}"
|
||||||
yield "}"
|
yield "}"
|
||||||
|
|
||||||
def render_mask_switches(body_func, by_mask):
|
def render_mask_switches(body_func, by_mask, discriminators):
|
||||||
yield "{"
|
yield "{"
|
||||||
for mask, instructions in by_mask.items():
|
for mask, instructions in by_mask.items():
|
||||||
instructions = sorted(instructions, key=lambda i: i.code.code_bits)
|
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 "return DECODE__UNDEFINED;"
|
||||||
yield "}"
|
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 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 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():
|
def header_execute():
|
||||||
yield '#include "decode_execute.h"'
|
yield '#include "decode_execute.h"'
|
||||||
@ -81,27 +88,78 @@ def header_print():
|
|||||||
yield '#include "decode_print.h"'
|
yield '#include "decode_print.h"'
|
||||||
yield ""
|
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():
|
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)
|
by_mask = defaultdict(list)
|
||||||
masks = []
|
masks = []
|
||||||
|
|
||||||
for ins in untabulate_instructions_sh4():
|
for ins in untabulate_instructions_sh4():
|
||||||
if ins.instruction in disabled_instructions:
|
if ins.instruction in disabled_instructions:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if ins.code.mask_bits not in masks:
|
if ins.code.mask_bits not in masks:
|
||||||
masks.append(ins.code.mask_bits)
|
masks.append(ins.code.mask_bits)
|
||||||
by_mask[ins.code.mask_bits].append(ins)
|
by_mask[ins.code.mask_bits].append(ins)
|
||||||
|
|
||||||
render, out = renderer()
|
render, out = renderer()
|
||||||
render(header_execute())
|
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:
|
with open(sys.argv[1], 'w') as f:
|
||||||
f.write(out.getvalue())
|
f.write(out.getvalue())
|
||||||
|
|
||||||
render, out = renderer()
|
render, out = renderer()
|
||||||
render(header_print())
|
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:
|
with open(sys.argv[2], 'w') as f:
|
||||||
f.write(out.getvalue())
|
f.write(out.getvalue())
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ from ast_transformers import transform_statements
|
|||||||
|
|
||||||
from instruction_table import untabulate_instructions_sh4
|
from instruction_table import untabulate_instructions_sh4
|
||||||
from instruction_table import untabulate_instructions_sh2
|
from instruction_table import untabulate_instructions_sh2
|
||||||
|
from instruction_table import unparse_instruction_code
|
||||||
from instruction_function_name import instruction_function_name
|
from instruction_function_name import instruction_function_name
|
||||||
from instruction_file_name import instruction_file_name
|
from instruction_file_name import instruction_file_name
|
||||||
from instruction_properties import has_delay_slot
|
from instruction_properties import has_delay_slot
|
||||||
@ -17,21 +18,22 @@ from disabled_instructions import disabled_instructions
|
|||||||
def is_instruction_descriptor(s):
|
def is_instruction_descriptor(s):
|
||||||
return all(c in {'0', '1', 'n', 'm', 'i', 'd'} for c in s)
|
return all(c in {'0', '1', 'n', 'm', 'i', 'd'} for c in s)
|
||||||
|
|
||||||
def parse_file(path):
|
def parse_header(buf):
|
||||||
with open(path) as f:
|
lines = buf.split('\n')
|
||||||
buf = f.read()
|
code, available, *rest = lines
|
||||||
|
assert len(code) == 16 and is_instruction_descriptor(lines[0]), lines[0]
|
||||||
lines = buf.split('\n', maxsplit=2)
|
if not available.startswith('Available only when'):
|
||||||
assert len(lines[0]) == 16 and is_instruction_descriptor(lines[0]), lines[0]
|
return code, None, '\n'.join([available, *rest])
|
||||||
|
|
||||||
if lines[1].startswith('Available only when'):
|
|
||||||
buf = lines[2]
|
|
||||||
else:
|
else:
|
||||||
if len(lines) >= 3:
|
return code, available, '\n'.join(rest)
|
||||||
buf = '\n'.join([lines[1], lines[2]])
|
|
||||||
else:
|
|
||||||
buf = lines[1]
|
|
||||||
|
|
||||||
|
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)
|
lexer = Lexer(buf)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
@ -54,9 +56,12 @@ def generate_function_declaration(instruction_name, function_name, variables):
|
|||||||
yield f"/* {instruction_name} */"
|
yield f"/* {instruction_name} */"
|
||||||
yield f"void {function_name}({args})"
|
yield f"void {function_name}({args})"
|
||||||
|
|
||||||
def generate_file(instruction_name, function_name, variables, delay_slot, src_path):
|
def generate_file(instruction_name, function_name, ins, delay_slot):
|
||||||
print(instruction_name)
|
buf = read_ins_source(ins)
|
||||||
tokens = list(parse_file(src_path))
|
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)
|
parser = Parser(tokens)
|
||||||
statements = []
|
statements = []
|
||||||
while parser.tokens[parser.pos:]:
|
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)
|
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 "{"
|
yield "{"
|
||||||
output = []
|
output = []
|
||||||
for statement in statements:
|
for statement in statements:
|
||||||
@ -104,10 +109,8 @@ def main():
|
|||||||
_name = [ins.instruction, ins.operands] if ins.operands else [ins.instruction]
|
_name = [ins.instruction, ins.operands] if ins.operands else [ins.instruction]
|
||||||
instruction_name = " ".join(_name)
|
instruction_name = " ".join(_name)
|
||||||
function_name = instruction_function_name(ins)
|
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"
|
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)
|
output.extend(gen)
|
||||||
|
|
||||||
gen = generate_function_declaration(instruction_name, function_name, ins.variables)
|
gen = generate_function_declaration(instruction_name, function_name, ins.variables)
|
||||||
|
@ -1,14 +1,12 @@
|
|||||||
from instruction_table import untabulate_instructions_sh4
|
from instruction_table import untabulate_instructions_sh4
|
||||||
|
from instruction_table import unparse_instruction_code
|
||||||
from instruction_file_name import instruction_file_name
|
from instruction_file_name import instruction_file_name
|
||||||
|
|
||||||
for ins in untabulate_instructions_sh4():
|
for ins in untabulate_instructions_sh4():
|
||||||
code = list(f'{ins.code.code_bits:016b}')
|
code = unparse_instruction_code(ins)
|
||||||
for operand in ins.code.operands.values():
|
|
||||||
for i in range(operand.lsb, operand.lsb + operand.length):
|
|
||||||
code[15 - i] = operand.operand
|
|
||||||
|
|
||||||
file_name = instruction_file_name(ins)
|
file_name = instruction_file_name(ins)
|
||||||
path = os.path.join("sh4", file_name)
|
path = os.path.join("sh4", file_name)
|
||||||
assert not os.path.exists(path)
|
assert not os.path.exists(path)
|
||||||
with open(path, 'w') as f:
|
with open(path, 'w') as f:
|
||||||
f.write(''.join(code) + '\n')
|
f.write(code + '\n')
|
||||||
|
@ -4,14 +4,33 @@ from pprint import pprint
|
|||||||
import os
|
import os
|
||||||
import inspect
|
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:
|
class Instruction:
|
||||||
instruction: str
|
instruction: str
|
||||||
operands: str
|
operands: str
|
||||||
variables: list[str]
|
variables: list[str]
|
||||||
code: str
|
code: Code
|
||||||
operation: str
|
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 = {
|
_operands = {
|
||||||
"Rn",
|
"Rn",
|
||||||
"Rm",
|
"Rm",
|
||||||
@ -31,18 +50,6 @@ def _b16_str(n):
|
|||||||
def b16_str(n):
|
def b16_str(n):
|
||||||
return ''.join(_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 = {
|
_operand_bits = {
|
||||||
'i',
|
'i',
|
||||||
'n',
|
'n',
|
||||||
@ -190,9 +197,15 @@ def untabulate_instructions(filename, columns):
|
|||||||
assert '\t' not in line, line
|
assert '\t' not in line, line
|
||||||
if line and line[0] == ' ':
|
if line and line[0] == ' ':
|
||||||
assert len(line.strip()) == len(column("operation").strip())
|
assert len(line.strip()) == len(column("operation").strip())
|
||||||
instructions[-1].operation = " ".join([
|
instructions[-1] = Instruction(
|
||||||
instructions[-1].operation, line.strip()
|
instruction = instructions[-1].instruction,
|
||||||
])
|
operands = instructions[-1].operands,
|
||||||
|
variables = instructions[-1].variables,
|
||||||
|
code = instructions[-1].code,
|
||||||
|
operation = " ".join([
|
||||||
|
instructions[-1].operation, line.strip()
|
||||||
|
])
|
||||||
|
)
|
||||||
continue
|
continue
|
||||||
instruction = Instruction(*parse_instruction(**dict([
|
instruction = Instruction(*parse_instruction(**dict([
|
||||||
(name, line[start:end].strip())
|
(name, line[start:end].strip())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user