From abe293a0c6db0ad1cff41f857248832324d36f67 Mon Sep 17 00:00:00 2001 From: Andrew Cagney Date: Thu, 24 Apr 1997 12:06:27 +0000 Subject: [PATCH] Enable more instructions. --- sim/igen/ChangeLog | 21 +++ sim/igen/ld-insn.c | 77 +++++++---- sim/tic80/ChangeLog | 9 ++ sim/tic80/cpu.h | 6 +- sim/tic80/dc | 5 + sim/tic80/insns | 372 ++++++++++++++++++++++++++++---------------------- sim/tic80/interp.c | 15 +- sim/tic80/sim-calls.c | 45 +++++- sim/tic80/sim-main.h | 12 +- 9 files changed, 359 insertions(+), 203 deletions(-) diff --git a/sim/igen/ChangeLog b/sim/igen/ChangeLog index 2f61d58..4ea778f 100644 --- a/sim/igen/ChangeLog +++ b/sim/igen/ChangeLog @@ -1,3 +1,24 @@ +Thu Apr 24 11:43:45 1997 Andrew Cagney + + * ld-insn.c (insn_table_expand_opcode): Allow reserved fields to + be broken up. + (insn_table_expand_insns): Allow special rules to apply to groups + of instructions when all members of the group match the special + mask/value. + + * gen-semantics.c (print_c_semantic): Ditto. + * igen.c (print_semantic_function_formal): Ditto. + (print_semantic_function_type): Ditto. + * igen.c (print_icache_function_formal): Ditto. + * gen-idecode.c (print_idecode_issue_function_body): Ditto. + + * gen-idecode.c (gen_idecode_h): Prepend the global_prefix to the + instruction_address type. + + * gen-semantics.c (print_semantic_body): Call cpu_error when an + unimplemented instruction is encountered - gives the interpreter + the chance to stop correctly. + Wed Apr 23 20:06:36 1997 Andrew Cagney * igen.c (print_function_name): Allow dot's in instruction names. diff --git a/sim/igen/ld-insn.c b/sim/igen/ld-insn.c index a25ef04..4baa73d 100644 --- a/sim/igen/ld-insn.c +++ b/sim/igen/ld-insn.c @@ -175,9 +175,11 @@ parse_insn_format(table_entry *entry, new_field->is_int = 1; } } - else if (new_field->val_string[0] == '/' - || new_field->val_string[0] == '*') { - new_field->is_slash = 1; + else if (new_field->val_string[0] == '/') { + new_field->is_reserved = 1; + } + else if (new_field->val_string[0] == '*') { + new_field->is_wild = 1; } else { new_field->is_string = 1; @@ -504,7 +506,7 @@ insn_table_traverse_insn(insn_table *table, typedef enum { field_constant_int = 1, - field_constant_slash = 2, + field_constant_reserved = 2, field_constant_string = 3 } constant_field_types; @@ -517,8 +519,8 @@ insn_field_is_constant(insn_field *field, if (field->is_int) return field_constant_int; /* field is `/' and treating that as a constant */ - if (field->is_slash && rule->force_slash) - return field_constant_slash; + if (field->is_reserved && rule->force_reserved) + return field_constant_reserved; /* field, though variable is on the list */ if (field->is_string && rule->force_expansion != NULL) { char *forced_fields = rule->force_expansion; @@ -694,7 +696,7 @@ insn_table_expand_opcode(insn_table *table, } else { insn_field *field = instruction->fields->bits[field_nr]; - if (field->is_int || field->is_slash) { + if (field->is_int) { if (!(field->first >= table->opcode->first && field->last <= table->opcode->last)) error("%s:%d: Instruction field %s.%s [%d..%d] overlaps sub-field [%d..%d] boundary", @@ -703,7 +705,7 @@ insn_table_expand_opcode(insn_table *table, field->pos_string, field->val_string, field->first, field->last, table->opcode->first, table->opcode->last); - insn_table_expand_opcode(table, instruction, field->last+1, + insn_table_expand_opcode(table, instruction, field->last + 1, ((opcode_nr << field->width) + field->val_int), bits); } @@ -712,19 +714,25 @@ insn_table_expand_opcode(insn_table *table, int last_pos = ((field->last < table->opcode->last) ? field->last : table->opcode->last); int first_pos = ((field->first > table->opcode->first) - ? field->first : table->opcode->first); + ? field->first : table->opcode->first); int width = last_pos - first_pos + 1; - int last_val = (table->opcode->is_boolean - ? 2 : (1 << width)); - for (val = 0; val < last_val; val++) { - insn_bits *new_bits = ZALLOC(insn_bits); - new_bits->field = field; - new_bits->value = val; - new_bits->last = bits; - new_bits->opcode = table->opcode; - insn_table_expand_opcode(table, instruction, last_pos+1, - ((opcode_nr << width) | val), - new_bits); + if (field->is_reserved) + insn_table_expand_opcode(table, instruction, last_pos + 1, + ((opcode_nr << width)), + bits); + else { + int last_val = (table->opcode->is_boolean + ? 2 : (1 << width)); + for (val = 0; val < last_val; val++) { + insn_bits *new_bits = ZALLOC(insn_bits); + new_bits->field = field; + new_bits->value = val; + new_bits->last = bits; + new_bits->opcode = table->opcode; + insn_table_expand_opcode(table, instruction, last_pos+1, + ((opcode_nr << width) | val), + new_bits); + } } } } @@ -742,7 +750,18 @@ insn_table_insert_expanding(insn_table *table, } -extern void +static int +special_matches_all_insns (unsigned mask, unsigned value, insn *insns) +{ + insn *i; + for (i = insns; i != NULL; i = i->next) + if ((i->fields->value & mask) != value) + return 0; + return 1; +} + + +void insn_table_expand_insns(insn_table *table) { @@ -750,10 +769,17 @@ insn_table_expand_insns(insn_table *table) /* determine a valid opcode */ while (table->opcode_rule) { - /* specials only for single instructions */ + /* specials only for single instructions or normal rules when + matches all */ if ((table->nr_insn > 1 && table->opcode_rule->special_mask == 0 && table->opcode_rule->type == normal_decode_rule) + || (table->nr_insn > 1 + && table->opcode_rule->special_mask != 0 + && table->opcode_rule->type == normal_decode_rule + && special_matches_all_insns (table->opcode_rule->special_mask, + table->opcode_rule->special_value, + table->insns)) || (table->nr_insn == 1 && table->opcode_rule->special_mask != 0 && ((table->insns->fields->value @@ -822,8 +848,11 @@ dump_insn_field(insn_field *field, if (field->is_int) dumpf(indent, "(is_int %d)\n", field->val_int); - if (field->is_slash) - dumpf(indent, "(is_slash)\n"); + if (field->is_reserved) + dumpf(indent, "(is_wild)\n"); + + if (field->is_wild) + dumpf(indent, "(is_wild)\n"); if (field->is_string) dumpf(indent, "(is_string `%s')\n", field->val_string); diff --git a/sim/tic80/ChangeLog b/sim/tic80/ChangeLog index 37c6adb..248e46d 100644 --- a/sim/tic80/ChangeLog +++ b/sim/tic80/ChangeLog @@ -1,3 +1,12 @@ +Thu Apr 24 16:43:09 1997 Andrew Cagney + + * dc: Add additional rules so that minor opcode files are + detected. + * insns: Enable more instructions. + + * sim-calls.c (sim_fetch_register,sim_store_register, sim_write): + Implement. + Thu Apr 24 00:39:51 1997 Doug Evans * configure: Regenerated to track ../common/aclocal.m4 changes. diff --git a/sim/tic80/cpu.h b/sim/tic80/cpu.h index 4cb7178..4cfe6d2 100644 --- a/sim/tic80/cpu.h +++ b/sim/tic80/cpu.h @@ -1,7 +1,9 @@ typedef struct _sim_cpu { - unsigned_word reg[32]; - sim_cpu_base base; + unsigned32 reg[32]; + unsigned64 acc[2]; instruction_address cia; + sim_cpu_base base; } sim_cpu; #define GPR(N) ((CPU)->reg[N]) +#define ACC(N) ((CPU)->acc[N]) diff --git a/sim/tic80/dc b/sim/tic80/dc index efd6e41..4199826 100644 --- a/sim/tic80/dc +++ b/sim/tic80/dc @@ -1 +1,6 @@ +# most instructions switch: 21: 12: 21: 12 +switch: 11: 7: 6: 12 +#switch: 21: 13: 21: 13 +#switch: 12: 7: 6: 13 +switch: 27: 27: 27: 27 diff --git a/sim/tic80/insns b/sim/tic80/insns index 45347e4..53985ff 100644 --- a/sim/tic80/insns +++ b/sim/tic80/insns @@ -1,7 +1,7 @@ // The following is called when ever an illegal instruction is // encountered ::internal::illegal - engine_error (sd, cia, "illegal instruction at 0x%lx", cia.ip); + engine_error (SD, CPU, cia, "illegal instruction at 0x%lx", cia.ip); // Signed Integer Add - add source1, source2, dest void::function::do_add:signed32 *rDest, signed32 Source1, signed32 Source2 @@ -14,8 +14,8 @@ void::function::do_add:signed32 *rDest, signed32 Source1, signed32 Source2 31.Dest,26.Source2,21.0b11101100,13.0,12.0,11./,4.Source1::::add r do_add (_SD, rDest, rSource1, rSource2); 31.Dest,26.Source2,21.0b11101100,13.0,12.1,11./::::add l - long_immediate (LongSignedImmediateOffset); - do_add (_SD, rDest, LongSignedImmediateOffset, rSource2); + long_immediate (LongSignedImmediate); + do_add (_SD, rDest, LongSignedImmediate, rSource2); // Unsigned Integer Add - addu source1, source2, dest @@ -121,7 +121,7 @@ instruction_address::function::do_bcnd:instruction_address cia, instruction_addr case 0: val = SEXT32 (source, 7); break; case 1: val = SEXT32 (source, 15); break; case 2: val = source; break; - default: engine_error (sd, cia, "bcnd - reserved size"); + default: engine_error (SD, CPU, cia, "bcnd - reserved size"); } switch (code) { @@ -156,11 +156,11 @@ instruction_address::function::do_bcnd:instruction_address cia, instruction_addr // brcr #void::function::do_brcr:unsigned32 offset # sim_io_error ("brcr"); -#31.//,27.0,26.//,21.0b0000110,14.CRN::::brcr i +31.//,27.0,26.//,21.0b0000110,14.CRN::::brcr i # nia = do_brcr (_SD, rCRN_val); -#31.//,27.0,26.//,21.0b110000110,12.0,11./,4.Source1::::brcr r +31.//,27.0,26.//,21.0b110000110,12.0,11./,4.Source1::::brcr r # nia = do_brcr (_SD, CRN[rSource1]); -#31.//,27.0,26.//,21.0b110000110,12.1,11./::::brcr l +31.//,27.0,26.//,21.0b110000110,12.1,11./::::brcr l # nia = do_brcr (_SD, CRN[SL]); @@ -185,9 +185,9 @@ instruction_address::function::do_bsr:instruction_address cia, instruction_addre // cmnd -#31./,21.0b0000010,14.UI::::cmnd i -#31./,21.0b110000010,12.0,11./,4.Source1::::cmnd r -#31./,21.0b110000010,12.1,11./::::cmnd l +31./,21.0b0000010,14.UI::::cmnd i +31./,21.0b110000010,12.0,11./,4.Source1::::cmnd r +31./,21.0b110000010,12.1,11./::::cmnd l // cmp @@ -237,38 +237,40 @@ void::function::do_cmp:unsigned32 *rDest, unsigned32 Source1, unsigned32 Source2 // dld[{.b|.h|.d}] #void::function::do_dld:unsigned32 *rDest, unsigned32 Source1, unsigned32 Source2 # sim_io_error ("dld"); -#31.Dest,26.Source2,21.0b110100,m,sz,0,S,1,9./,4.Source1::::dld r +31.Dest,26.Base,21.0b110100,15.m,14.sz,12.0,11.S,10.1,9./,4.IndOff::::dld r # do_dld (_SD, rDest, rSource1, rSource2); -#31.Dest,26.Source2,21.0b11110100,m,sz,1,S,1,9./::::dld l +31.Dest,26.Base,21.0b110100,15.m,14.sz,12.1,11.S,10.1,9./::::dld l +# long_immediate (LongSignedImmediateOffset); # do_dld (_SD, rDest, LongSignedImmediate, rSource2); // dld.u[{.b|.h|.d}] #void::function::do_dld_u:unsigned32 *rDest, unsigned32 Source1, unsigned32 Source2 # sim_io_error ("dld.u"); -#31.Dest,26.Source2,21.0b110101,m,sz,0,S,1,9./,4.Source1::::dld.u r +31.Dest,26.Base,21.0b110101,15.m,14.sz,12.0,11.S,10.1,9./,4.IndOff::::dld.u r # do_dld_u (_SD, rDest, rSource1, rSource2); -#31.Dest,26.Source2,21.0b11110101,m,sz,1,S,1,9./::::dld.u l +31.Dest,26.Base,21.0b110101,15.m,14.sz,12.1,11.S,10.1,9./::::dld.u l +# long_immediate (LongSignedImmediateOffset); # do_dld_u (_SD, rDest, LongSignedImmediate, rSource2); // dst[{.b|.h|.d}] #void::function::do_dst:unsigned32 *rDest, unsigned32 Source1, unsigned32 Source2 # sim_io_error ("dst"); -#31.Dest,26.Source2,21.0b110110,m,sz,0,S,1,9./,4.Source1::::dst r +31.Dest,26.Base,21.0b110110,15.m,14.sz,12.0,11.S,10.1,9./,4.IndOff::::dst r # do_dst (_SD, rDest, rSource1, rSource2); -#31.Dest,26.Source2,21.0b11110110,m,sz,1,S,1,9./::::dst l +31.Dest,26.Base,21.0b110110,15.m,14.sz,12.1,11.S,10.1,9./::::dst l # do_dst (_SD, rDest, LongSignedImmediate, rSource2); // estop -#31./,21.0b1111111,1,0,0,11./::::estop +31./,21.0b1111111,14.1,13.0,12.0,11./::::estop // etrap -#31./,27.1,26./,21.0b0000001,14.UTN::::etrap i -#31./,27.1,26./,21.0b110000001,12.0,11./,4.iUTN::::etrap r -#31./,27.1,26./,21.0b110000001,12.1,11./::::etrap l +31./,27.1,26./,21.0b0000001,14.UTN::::etrap i +31./,27.1,26./,21.0b110000001,12.0,11./,4.iUTN::::etrap r +31./,27.1,26./,21.0b110000001,12.1,11./::::etrap l // exts - see shift.ds @@ -280,99 +282,99 @@ void::function::do_cmp:unsigned32 *rDest, unsigned32 Source1, unsigned32 Source2 // fadd.{s|d}{s|d}{s|d} #void::function::do_fadd:unsigned32 *rDest, unsigned32 Source1, unsigned32 Source2 # sim_io_error ("fadd"); -#31.Dest,26.Source2,21.0b111110000,0,r,PD,P2,P1,4.Source1::::fadd r +31.Dest,26.Source2,21.0b111110000,12.0,11.r,10.PD,8.P2,6.P1,4.Source1::::fadd r # do_fadd (_SD, rDest, rSource1, rSource2); -#31.Dest,26.Source2,21.0b11111110000,1,r,PD,P2,P1,4./::::fadd l +31.Dest,26.Source2,21.0b111110000,12.1,11.r,10.PD,8.P2,6.P1,4./::::fadd l # do_fadd (_SD, rDest, LongSignedImmediate, rSource2); // fcmp.{s|d}{s|d}{s|d} #void::function::do_fcmp:unsigned32 *rDest, unsigned32 Source1, unsigned32 Source2 # sim_io_error ("fcmp"); -#31.Dest,26.Source2,21.0b111110101,0,/,00,P2,P1,4.Source1::::fcmp r +31.Dest,26.Source2,21.0b111110101,12.0,11./,10.0,8.P2,6.P1,4.Source1::::fcmp r # do_fcmp (_SD, rDest, rSource1, rSource2); -#31.Dest,26.Source2,21.0b11111110101,1,/,00,P2,P1,4./::::fcmp l +31.Dest,26.Source2,21.0b111110101,12.1,11./,10.0,8.P2,6.P1,4./::::fcmp l # do_fcmp (_SD, rDest, LongSignedImmediate, rSource2); // fdiv.{s|d}{s|d}{s|d} #void::function::do_fdiv:unsigned32 *rDest, unsigned32 Source1, unsigned32 Source2 # sim_io_error ("fdiv"); -#31.Dest,26.Source2,21.0b111110011,0,/,PD,P2,P1,4.Source1::::fdiv r +31.Dest,26.Source2,21.0b111110011,12.0,11./,10.PD,8.P2,6.P1,4.Source1::::fdiv r # do_fdiv (_SD, rDest, rSource1, rSource2); -#31.Dest,26.Source2,21.0b11111110011,1,/,PD,P2,P1,4./::::fdiv l +31.Dest,26.Source2,21.0b111110011,12.1,11./,10.PD,8.P2,6.P1,4./::::fdiv l # do_fdiv (_SD, rDest, LongSignedImmediate, rSource2); // fmpy.{s|d|i|u}{s|d|i|u}{s|d|i|u} #void::function::do_fmpy:unsigned32 *rDest, unsigned32 Source1, unsigned32 Source2 # sim_io_error ("fmpy"); -#31.Dest,26.Source2,21.0b111110010,0,/,PD,P2,P1,4.Source1::::fmpy r +31.Dest,26.Source2,21.0b111110010,12.0,11./,10.PD,8.P2,6.P1,4.Source1::::fmpy r # do_fmpy (_SD, rDest, rSource1, rSource2); -#31.Dest,26.Source2,21.0b11111110010,1,/,PD,P2,P1,4./::::fmpy l +31.Dest,26.Source2,21.0b111110010,12.1,11./,10.PD,8.P2,6.P1,4./::::fmpy l # do_fmpy (_SD, rDest, LongSignedImmediate, rSource2); // frndm.{s|d|i|u}{s|d|i|u}{s|d|i|u} #void::function::do_frndm:unsigned32 *rDest, unsigned32 Source1, unsigned32 Source2 # sim_io_error ("frndm"); -#31.Dest,26.Source2,21.0b111110100,0,r,PD,11,P1,4.Source1::::frndm r +31.Dest,26.Source2,21.0b111110100,12.0,11.r,10.PD,8.0b11,6.P1,4.Source1::::frndm r # do_frndm (_SD, rDest, rSource1, rSource2); -#31.Dest,26.Source2,21.0b11111110100,1,r,PD,11,P1,4./::::frndm l +31.Dest,26.Source2,21.0b111110100,12.1,11.r,10.PD,8.0b11,6.P1,4./::::frndm l # do_frndm (_SD, rDest, LongSignedImmediate, rSource2); // frndn.{s|d|i|u}{s|d|i|u}{s|d|i|u} #void::function::do_frndn:unsigned32 *rDest, unsigned32 Source1, unsigned32 Source2 # sim_io_error ("frndn"); -#31.Dest,26.Source2,21.0b111110100,0,r,PD,00,P1,4.Source1::::frndn r +31.Dest,26.Source2,21.0b111110100,12.0,11.r,10.PD,8.0b00,6.P1,4.Source1::::frndn r # do_frndn (_SD, rDest, rSource1, rSource2); -#31.Dest,26.Source2,21.0b11111110100,1,r,PD,00,P1,4./::::frndn l +31.Dest,26.Source2,21.0b111110100,12.1,11.r,10.PD,8.0b00,6.P1,4./::::frndn l # do_frndn (_SD, rDest, LongSignedImmediate, rSource2); // frndp.{s|d|i|u}{s|d|i|u}{s|d|i|u} #void::function::do_frndp:unsigned32 *rDest, unsigned32 Source1, unsigned32 Source2 # sim_io_error ("frndp"); -#31.Dest,26.Source2,21.0b111110100,0,r,PD,10,P1,4.Source1::::frndp r +#31.Dest,26.Source2,21.0b111110100,12.0,11.r,10.PD,8.0b10,6.P1,4.Source1::::frndp r # do_frndp (_SD, rDest, rSource1, rSource2); -#31.Dest,26.Source2,21.0b11111110100,1,r,PD,10,P1,4./::::frndp l +#31.Dest,26.Source2,21.0b111110100,12.1,11.r,10.PD,8.0b10,6.P1,4./::::frndp l # do_frndp (_SD, rDest, LongSignedImmediate, rSource2); // frndz.{s|d|i|u}{s|d|i|u}{s|d|i|u} #void::function::do_frndz:unsigned32 *rDest, unsigned32 Source1, unsigned32 Source2 # sim_io_error ("frndz"); -#31.Dest,26.Source2,21.0b111110100,0,r,PD,01,P1,4.Source1::::frndz r +31.Dest,26.Source2,21.0b111110100,12.0,11.r,10.PD,8.0b01,6.P1,4.Source1::::frndz r # do_frndz (_SD, rDest, rSource1, rSource2); -#31.Dest,26.Source2,21.0b11111110100,1,r,PD,01,P1,4./::::frndz l +31.Dest,26.Source2,21.0b111110100,12.1,11.r,10.PD,8.0b01,6.P1,4./::::frndz l # do_frndz (_SD, rDest, LongSignedImmediate, rSource2); // fsqrt.{s|d}{s|d}{s|d} #void::function::do_fsqrt:unsigned32 *rDest, unsigned32 Source1, unsigned32 Source2 # sim_io_error ("fsqrt"); -#31.Dest,26.Source2,21.0b111110111,0,/,PD,//,P1,4.Source1::::fsqrt r +31.Dest,26.Source2,21.0b111110111,12.0,11./,10.PD,8.//,6.P1,4.Source1::::fsqrt r # do_fsqrt (_SD, rDest, rSource1, rSource2); -#31.Dest,26.Source2,21.0b11111110111,1,/,PD,//,P1,4./::::fsqrt l +31.Dest,26.Source2,21.0b111110111,12.1,11./,10.PD,8.//,6.P1,4./::::fsqrt l # do_fsqrt (_SD, rDest, LongSignedImmediate, rSource2); // fsub.{s|d}{s|d}{s|d} #void::function::do_fsub:unsigned32 *rDest, unsigned32 Source1, unsigned32 Source2 # sim_io_error ("fsub"); -#31.Dest,26.Source2,21.0b111110001,0,r,PD,P2,P1,4.Source1::::fsub r +31.Dest,26.Source2,21.0b111110001,12.0,11.r,10.PD,8.P2,6.P1,4.Source1::::fsub r # do_fsub (_SD, rDest, rSource1, rSource2); -#31.Dest,26.Source2,21.0b11111110001,1,r,PD,P2,P1,4./::::fsub l +31.Dest,26.Source2,21.0b111110001,12.1,11.r,10.PD,8.P2,6.P1,4./::::fsub l # do_fsub (_SD, rDest, LongSignedImmediate, rSource2); // illop -#31./,21.0b0000000,14./::::illop -#31./,21.0b111111111,12./::::illop l +31./,21.0b0000000,14./::::illop +31./,21.0b111111111,12./::::illop l -// ins - see shift.im +// ins - see sl.im // jsr[.a] @@ -396,36 +398,75 @@ instruction_address::function::do_jsr:instruction_address cia, instruction_addre // ld[{.b.h.d}] -#void::function::do_ld:unsigned32 *rDest, unsigned32 Source1, unsigned32 Source2 -# sim_io_error ("dld.u"); -#31.Dest,26.Base,21.0b0100,17.m,16.sz,14.SignedOffset::::ld i -# do_ld (_SD, rDest, rSource1, rSource2); -#31.Dest,26.Base,21.0b110100,15.m,14.sz,12.0,11.S,10.0,9./,4.IndOff::::ld r -# do_ld (_SD, rDest, , rSource2); -#31.Dest,26.Base,21.0b110100,15.m,14.sz,12.1,11.S,10.0,9./::::ld l -# long_immediate (LongSignedImmediate); -# do_ld (_SD, rDest, LongSignedImmediate, rSource2); +void::function::do_ld:instruction_address cia, unsigned32 *rDest, unsigned32 Base, unsigned32 *rBase, int m , int sz, int S, unsigned32 Offset + unsigned32 addr; + switch (sz) + { + case 0: + addr = Base + (S ? (Offset << 0) : Offset); + *rDest = MEM (signed, addr, 1); + break; + case 1: + addr = Base + (S ? (Offset << 1) : Offset); + *rDest = MEM (signed, addr, 2); + break; + case 2: + addr = Base + (S ? (Offset << 2) : Offset); + *rDest = MEM (signed, addr, 4); + break; + case 3: + engine_error (SD, CPU, cia, "ld.d broken"); + addr = Base + (S ? (Offset << 3) : Offset); + *rDest = MEM (signed, addr, 8); + break; + default: + addr = -1; + engine_error (SD, CPU, cia, "ld - invalid sz %d", sz); + } + if (m) + *rBase = addr; +31.Dest,26.Base,21.0b0100,17.m,16.sz,14.SignedOffset::::ld i + do_ld (_SD, cia, rDest, rBase, &GPR(Base), m, sz, 0, vSignedOffset); +31.Dest,26.Base,21.0b110100,15.m,14.sz,12.0,11.S,10.0,9./,4.IndOff::::ld r + do_ld (_SD, cia, rDest, rBase, &GPR(Base), m, sz, S, rIndOff); +31.Dest,26.Base,21.0b110100,15.m,14.sz,12.1,11.S,10.0,9./::::ld l + long_immediate (LongSignedImmediateOffset); + do_ld (_SD, cia, rDest, rBase, &GPR(Base), m, sz, S, LongSignedImmediateOffset); // ld.u[{.b.h.d}] -#void::function::do_ld_u:unsigned32 *rDest, unsigned32 Source1, unsigned32 Source2 -# sim_io_error ("dld.u"); -#31.Dest,26.Base,21.0b0101,17.m,16.sz,14.SignedOffset::::ld.u i -# do_ld_u (_SD, rDest, rSource1, rSource2); -#31.Dest,26.Base,21.0b110101,15.m,14.sz,12.0,11.S,10.0,9./,4.IndOff::::ld.u r -# do_ld_u (_SD, rDest, LongSignedImmediate, rSource2); -#31.Dest,26.Base,21.0b110101,15.m,14.sz,12.1,11.S,10.0,9./::::ld.u l -# long_immediate (LongSignedImmediateOffset); -# do_ld_u (_SD, rDest, LongSignedImmediateOffset, rSource2); +void::function::do_ld_u:instruction_address cia, unsigned32 *rDest, unsigned32 Base, unsigned32 *rBase, int m , int sz, int S, unsigned32 Offset + unsigned32 addr; + switch (sz) + { + case 0: + addr = Base + (S ? (Offset << 0) : Offset); + *rDest = MEM (unsigned, addr, 1); + break; + case 1: + addr = Base + (S ? (Offset << 1) : Offset); + *rDest = MEM (unsigned, addr, 2); + break; + default: + addr = -1; + engine_error (SD, CPU, cia, "ld.u - invalid sz %d", sz); + } + if (m) + *rBase = addr; +31.Dest,26.Base,21.0b0101,17.m,16.sz,14.SignedOffset::::ld.u i + do_ld_u (_SD, cia, rDest, rBase, &GPR(Base), m, sz, 0, vSignedOffset); +31.Dest,26.Base,21.0b110101,15.m,14.sz,12.0,11.S,10.0,9./,4.IndOff::::ld.u r + do_ld_u (_SD, cia, rDest, rBase, &GPR(Base), m, sz, S, rIndOff); +31.Dest,26.Base,21.0b110101,15.m,14.sz,12.1,11.S,10.0,9./::::ld.u l + long_immediate (LongSignedImmediateOffset); + do_ld_u (_SD, cia, rDest, rBase, &GPR(Base), m, sz, S, LongSignedImmediateOffset); // lmo -#31.Dest,26.Source,21.111111000,12.0,11./::::lmo +31.Dest,26.Source,21.111111000,12.0,11./::::lmo -// nop -31./,26./,21.0b0000100,14.0,11.0::::nop - /* NOP */ +// nop - see rdcr 0, r0 void::function::do_or:unsigned32 *rDest, unsigned32 Source1, unsigned32 Source2 @@ -473,89 +514,121 @@ void::function::do_or:unsigned32 *rDest, unsigned32 Source1, unsigned32 Source2 // rdcr -#31.Dest,26.0,21.0b0000100,14.UCRN::::rdcr i -#31.Dest,26.0,21.0b110000100,0,11./,4.INDCR::::rdcr r -#31.Dest,26.0,21.0b110000100,1,11./::::rdcr l +31.Dest,26.0,21.0b0000100,14.UCRN::::rdcr i +31.Dest,26.0,21.0b110000100,12.0,11./,4.INDCR::::rdcr r +31.Dest,26.0,21.0b110000100,12.1,11./::::rdcr l // rmo -#31.Dest,26.Source,21.0b111111001,0,11./::::rmo +31.Dest,26.Source,21.0b111111001,12.0,11./::::rmo -// rotl - see shift.dz +// rotl - see sl.dz -//rotr - see shift.dz +//rotr - see sl.dz -// shl - see shift.iz +// shl - see sl.iz // sl.{d|e|i}{m|s|z} -#31.Dest,26.Source,21.0b0001,17.Merge,14./,11.0,0,9.EndMask::::4.Rotate:sl i -#31.Dest,26.Source,21.0b110001,15.Merge,12.0,11.0,0,9.EndMask::::4.RotReg:sl r +31.Dest,26.Source,21.0b0001,17.Merge,14./,11.0,10.0,9.EndMask,4.Rotate::::sl i +31.Dest,26.Source,21.0b110001,15.Merge,12.0,11.0,10.0,9.EndMask,4.RotReg::::sl r // sli.{d|e|i}{m|s|z} -#31.Dest,26.Source,21.0b0001,17.Merge,14./,11.1,0,9.EndMask::::4.Rotate:sli i -#31.Dest,26.Source,21.0b110001,15.Merge,12.0,11.1,0,9.EndMask::::4.RotReg:sli r +31.Dest,26.Source,21.0b0001,17.Merge,14./,11.1,10.0,9.EndMask,4.Rotate::::sli i +31.Dest,26.Source,21.0b110001,15.Merge,12.0,11.1,10.0,9.EndMask,4.RotReg::::sli r // sr.{d|e|i}{m|s|z} -#31.Dest,26.Source,21.0b0001,17.Merge,14./,11.0,1,9.EndMask::::4.Rotate:sr i -#31.Dest,26.Source,21.0b110001,15.Merge,12.0,11.0,1,9.EndMask::::4.RotReg:sr r +31.Dest,26.Source,21.0b0001,17.Merge,14./,11.0,10.1,9.EndMask,4.Rotate::::sr i +31.Dest,26.Source,21.0b110001,15.Merge,12.0,11.0,10.1,9.EndMask,4.RotReg::::sr r // sra - see sr.es // sri.{d|e|i}{m|s|z} -#31.Dest,26.Source,21.0b0001,17.Merge,14./,11.1,1,9.EndMask::::4.Rotate:sri i -#31.Dest,26.Source,21.0b110001,15.Merge,12.0,11.1,1,9.EndMask::::4.RotReg:sri r +31.Dest,26.Source,21.0b0001,17.Merge,14./,11.1,10.1,9.EndMask,4.Rotate::::sri i +31.Dest,26.Source,21.0b110001,15.Merge,12.0,11.1,10.1,9.EndMask,4.RotReg::::sri r // srl - see sr.ez // st[{.b|.h|.d}] -#31.Dest,26.Base,21.0b0110,m,sz,14.SO::::st i -#31.Dest,26.Base,21.0b110110,m,sz,0,S,0,14./,4.IO::::st i -#31.Dest,26.Base,21.0b110110,m,sz,1,S,0,14./::::st i +void::function::do_st:instruction_address cia, unsigned32 rSource, unsigned32 Base, unsigned32 *rBase, int m , int sz, int S, unsigned32 Offset + unsigned32 addr; + switch (sz) + { + case 0: + addr = Base + (S ? (Offset << 0) : Offset); + STORE (addr, 1, rSource); + break; + case 1: + addr = Base + (S ? (Offset << 1) : Offset); + STORE (addr, 2, rSource); + break; + case 2: + addr = Base + (S ? (Offset << 2) : Offset); + STORE (addr, 4, rSource); + break; + case 3: + engine_error (SD, CPU, cia, "st.d broken"); + addr = Base + (S ? (Offset << 3) : Offset); + STORE (addr, 8, rSource); + break; + default: + addr = -1; + engine_error (SD, CPU, cia, "ld - invalid sz %d", sz); + } + if (m) + *rBase = addr; +31.Source,26.Base,21.0b0110,17.m,16.sz,14.SignedOffset::::st i + do_st (_SD, cia, rSource, rBase, &GPR(Base), m, sz, 0, vSignedOffset); +31.Source,26.Base,21.0b110110,15.m,14.sz,12.0,11.S,10.0,9./,4.IndOff::::st r + do_st (_SD, cia, rSource, rBase, &GPR(Base), m, sz, S, rIndOff); +31.Source,26.Base,21.0b110110,15.m,14.sz,12.1,11.S,10.0,9./::::st l + long_immediate (LongSignedImmediateOffset); + do_st (_SD, cia, rSource, rBase, &GPR(Base), m, sz, S, LongSignedImmediateOffset); // sub -#void::function::do_sub:signed32 *rDest, signed32 Source1, signed32 Source2 -# ALU_BEGIN (Source1); -# ALU_SUB (Source2); -# ALU_END (*rD); -#31.Dest,26.Source2,21.0b101100,0,14.SignedImmediate::::sub i -# do_sub (_SD, rDest, SI, rSource2); -#31.Dest,26.Source2,21.0b11101100,0,0,11./,4.Source1::::sub r -# do_sub (_SD, rDest, rSource1, rSource2); -#31.Dest,26.Source2,21.0b11101100,0,1,11./::::sub l -# do_sub (_SD, rDest, LongSignedImmediate, rSource2); +void::function::do_sub:signed32 *rDest, signed32 Source1, signed32 Source2 + ALU_BEGIN (Source1); + ALU_SUB (Source2); + ALU_END (*rDest); +// FIXME - the book has 15.1 which conflicts with subu. +31.Dest,26.Source2,21.0b101101,15.0,14.SignedImmediate::::sub i + do_sub (_SD, rDest, vSource1, rSource2); +31.Dest,26.Source2,21.0b11101101,13.0,12.0,11./,4.Source1::::sub r + do_sub (_SD, rDest, rSource1, rSource2); +31.Dest,26.Source2,21.0b11101101,13.0,12.1,11./::::sub l + long_immediate (LongSignedImmediate); + do_sub (_SD, rDest, LongSignedImmediate, rSource2); // subu -#void::function::do_subu:signed32 *rDest, signed32 Source1, signed32 Source2 -# ALU_BEGIN (Source1); -# ALU_SUBU (Source2); -# ALU_END (*rD); -#31.Dest,26.Source,21.0b101100,0,14.SignedImmediate::::subu i -# do_subu (_SD, rDest, SI, rSource2); -#31.Dest,26.Source,21.0b11101100,0,0,11./,4.Source1::::subu r -# do_subu (_SD, rDest, rSource1, rSource2); -#31.Dest,26.Source,21.0b11101100,0,1,11./::::subu l -# do_subu (_SD, rDest, LongSignedImmediate, rSource2); +void::function::do_subu:signed32 *rDest, signed32 Source1, signed32 Source2 + *rDest = Source1 - Source2; +31.Dest,26.Source2,21.0b101101,15.1,14.SignedImmediate::::subu i + do_subu (_SD, rDest, vSource1, rSource2); +31.Dest,26.Source2,21.0b11101101,13.1,12.0,11./,4.Source1::::subu r + do_subu (_SD, rDest, rSource1, rSource2); +31.Dest,26.Source2,21.0b11101101,13.1,12.1,11./::::subu l + long_immediate (LongSignedImmediate); + do_subu (_SD, rDest, LongSignedImmediate, rSource2); // swcr #void::function::do_swcr:signed32 *rDest, signed32 Source1, signed32 Source2 -#31.Dest,26.Source,21.0b000010,1,14.SignedImmediate::::swcr i +31.Dest,26.Source,21.0b000010,15.1,14.SignedImmediate::::swcr i # do_swcr (_SD, rDest, SI, rSource2); -#31.Dest,26.Source,21.0b11000010,1,0,11./,4.INDCR::::swcr r +31.Dest,26.Source,21.0b11000010,13.1,12.0,11./,4.INDCR::::swcr r # do_swcr (_SD, rDest, rSource1, rSource2); -#31.Dest,26.Source,21.0b11000010,1,1,11./::::swcr l +31.Dest,26.Source,21.0b11000010,13.1,12.1,11./::::swcr l # do_swcr (_SD, rDest, LongSignedImmediate, rSource2); @@ -567,14 +640,14 @@ void::function::do_trap:instruction_address cia, unsigned32 trap_number { case 1: /* EXIT */ { - engine_halt (SD, cia, sim_exited, GPR(3)); + engine_halt (SD, CPU, cia, sim_exited, GPR(3)); break; } case 4: /* WRITE */ { int i; if (GPR(3) != 1) - engine_error (SD, cia, "write to invalid fid %d", GPR(3)); + engine_error (SD, CPU, cia, "write to invalid fid %d", GPR(3)); for (i = 0; i < GPR(5); i++) { char c; @@ -585,7 +658,7 @@ void::function::do_trap:instruction_address cia, unsigned32 trap_number break; } default: - engine_error (SD, cia, "unknown trap %d", GPR(2)); + engine_error (SD, CPU, cia, "unknown trap %d", GPR(2)); } } 31./,27.0,26./,21.0b0000001,14.UTN::::trap i @@ -598,93 +671,68 @@ void::function::do_trap:instruction_address cia, unsigned32 trap_number // vadd.{s|d}{s|d} -#void::function::do_vadd:signed32 *rDest, signed32 Source1, signed32 Source2 -#31.*,26.Dest,21.0b11110,r,000,r,*,**,7.PD,6.*,5.P1,4.Source::::vadd r -# do_vadd (_SD, rDest, SI, rSource2); -#31.*,26.Dest,21.0b1111110,r,000,r,*,**,7.PD,6.*,5.P1,4./::::vadd l -# do_vadd (_SD, rDest, LongSignedImmediate, rSource2); +31.*,26.Dest,21.0b11110,16./,15.0b000,12.0,11./,10.*,9.*,7.PD,6.*,5.P1,4.Source::::vadd r +31.*,26.Dest,21.0b11110,16./,15.0b000,12.1,11./,10.*,9.*,7.PD,6.*,5.P1,4.Source::::vadd l -// vld{0|1}.{s|d} -#31.Dest,26.*,21.0b11110,18.*,10.1,S,**,p,******::::vld r +// vld{0|1}.{s|d} - see above - same instruction +#31.Dest,26.*,21.0b11110,18.*,10.1,9.S,8.*,6.p,7.******::::vld // vmac.ss{s|d} -#31.*,26.Source2,21.0b11110,a,110,0,a,**,Z,r,*,r,4.Source1::::vmac.ss ra -#31.Dest,26.Source2,21.0b11110,a,110,0,a,**,Z,r,*,r,4.Source1::::vmac.ss rr -#31.*,26.Source2,21.0b11110,a,110,0,a,**,Z,r,*,r,4.Source1::::vmac.ss ia -#31.Dest,26.Source2,21.0b11110,a,110,0,a,**,Z,r,*,r,4.Source1::::vmac.ss ir +#31.*, 26.Source2,21.0b11110,16.a0,15.0b110,12.0,11.a1,10.*,9.*, 8.Z,7./,6.*,5./,4.Source1::::vmac.ss ra +31.Dest,26.Source2,21.0b11110,16.a0,15.0b110,12.0,11.a1,10.0,9.PD,8.Z,7./,6.0,5./,4.Source1::::vmac.ss rr +#31.*, 26.Source2,21.0b11110,16.a0,15.0b110,12.1,11.a1,10.*,9.*, 8.Z,7./,6.*,5./,4./::::vmac.ss ia +31.Dest,26.Source2,21.0b11110,16.a0,15.0b110,12.1,11.a1,10.0,9.PD,8.Z,7./,6.0,5./,4./::::vmac.ss ir // vmpy.{s|d}{s|d} -#void::function::do_vmpy:signed32 *rDest, signed32 Source1, signed32 Source2 -#31.*,26.Dest,21.0b11110,r,000,r,*,**,7.PD,6.*,5.P1,4.Source::::vmpy r -# do_vmpy (_SD, rDest, SI, rSource2); -#31.*,26.Dest,21.0b1111110,r,000,r,*,**,7.PD,6.*,5.P1,4./::::vmpy l -# do_vmpy (_SD, rDest, LongSignedImmediate, rSource2); +31.*,26.Dest,21.0b11110,16./,15.0b010,12.0,11./,10.*,8.*,7.PD,6.*,5.P1,4.Source::::vmpy r +31.*,26.Dest,21.0b11110,16./,15.0b010,12.1,11./,10.*,8.*,7.PD,6.*,5.P1,4./::::vmpy l // vmsc.ss{s|d} -#31.*,26.Source2,21.0b11110,a,110,0,a,**,Z,r,*,r,4.Source1::::vmsc.ss ra -#31.Dest,26.Source2,21.0b11110,a,110,0,a,**,Z,r,*,r,4.Source1::::vmsc.ss rr -#31.*,26.Source2,21.0b11110,a,110,0,a,**,Z,r,*,r,4.Source1::::vmsc.ss ia -#31.Dest,26.Source2,21.0b11110,a,110,0,a,**,Z,r,*,r,4.Source1::::vmsc.ss ir +#31.*, 26.Source2,21.0b11110,16.a0,15.0b111,12.0,11.a1,10.*,9.*, 8.Z,7./,6.*,5./,4.Source1::::vmsc.ss ra +31.Dest,26.Source2,21.0b11110,16.a0,15.0b111,12.0,11.a1,10.0,9.PD,8.Z,7./,6.0,5./,4.Source1::::vmsc.ss rr +#31.*, 26.Source2,21.0b11110,16.a0,15.0b111,12.1,11.a1,10.*,9.*, 8.Z,7./,6.*,5./,4./::::vmsc.ss ia +31.Dest,26.Source2,21.0b11110,16.a0,15.0b111,12.1,11.a1,10.0,9.PD,8.Z,7./,6.0,5./,4./::::vmsc.ss ir // vmsub.{s|d}{s|d} -#void::function::do_vmsub:signed32 *rDest, signed32 Source1, signed32 Source2 -#31.*,26.Dest,21.0b11110,r,000,r,*,**,7.PD,6.*,5.P1,4.Source::::vmsub r -# do_vmsub (_SD, rDest, SI, rSource2); -#31.*,26.Dest,21.0b1111110,r,000,r,*,**,7.PD,6.*,5.P1,4./::::vmsub l -# do_vmsub (_SD, rDest, LongSignedImmediate, rSource2); +31.*,26.Dest,21.0b11110,16.a0,15.0b011,12.0,11.a1,10.*,8.Z,7.PD,6.*,5./,4.Source::::vmsub r +31.*,26.Dest,21.0b11110,16.a0,15.0b011,12.1,11.a1,10.*,8.Z,7.PD,6.*,5./,4./::::vmsub l // vrnd.{s|d}{s|d} -#void::function::do_vrnd:signed32 *rDest, signed32 Source1, signed32 Source2 -#31.*,26.Dest,21.0b11110,r,000,r,*,**,7.PD,6.*,5.P1,4.Source::::vrnd r -# do_vrnd (_SD, rDest, SI, rSource2); -#31.*,26.Dest,21.0b1111110,r,000,r,*,**,7.PD,6.*,5.P1,4./::::vrnd l -# do_vrnd (_SD, rDest, LongSignedImmediate, rSource2); +31.*,26.Dest,21.0b11110,16.a0,15.0b100,12.0,11.a1,10.*,8.PD,6.*,5.P1,4.Source::::vrnd f r +31.*,26.Dest,21.0b11110,16.a0,15.0b100,12.1,11.a1,10.*,8.PD,6.*,5.P1,4./::::vrnd f l // vrnd.{i|u}{s|d} -#void::function::do_vrnd:signed32 *rDest, signed32 Source1, signed32 Source2 -#31.*,26.Dest,21.0b11110,r,000,r,*,**,7.PD,6.*,5.P1,4.Source::::vrnd r -# do_vrnd (_SD, rDest, SI, rSource2); -#31.*,26.Dest,21.0b1111110,r,000,r,*,**,7.PD,6.*,5.P1,4./::::vrnd l -# do_vrnd (_SD, rDest, LongSignedImmediate, rSource2); +31.*,26.Dest,21.0b11110,16./,15.0b101,12.0,11./,10.*,8./,7.PD,6.*,5.P1,4.Source::::vrnd i r +31.*,26.Dest,21.0b11110,16./,15.0b101,12.1,11./,10.*,8./,7.PD,6.*,5.P1,4./::::vrnd i l -// vst.{s|d} -#31.Source,26.*,21.0b1110,16.*,10.0,9.S,**,1,******::::vst +// vst.{s|d} - see above - same instruction +#31.Source,26.*,21.0b11110,16.*,10.0,9.S,8.*,6.1,5.*::::vst // vsub.{i|u}{s|d} -#void::function::do_vsub:signed32 *rDest, signed32 Source1, signed32 Source2 -#31.*,26.Dest,21.0b11110,r,000,r,*,**,7.PD,6.*,5.P1,4.Source::::vsub r -# do_vsub (_SD, rDest, SI, rSource2); -#31.*,26.Dest,21.0b1111110,r,000,r,*,**,7.PD,6.*,5.P1,4./::::vsub l -# do_vsub (_SD, rDest, LongSignedImmediate, rSource2); +31.*,26.Dest,21.0b11110,16./,15.0b001,12.0,11./,10.*,8./,7.PD,6.*,5.P1,4.Source::::vsub r +31.*,26.Dest,21.0b11110,16./,15.0b001,12.1,11./,10.*,8./,7.PD,6.*,5.P1,4./::::vsub l -// wrcr -#void::function::do_wrcr:signed32 *rDest, signed32 Source1, signed32 Source2 -#31.Dest,26.Source,21.0b000010,1,14.SignedImmediate::::wrcr i -# do_wrcr (_SD, rDest, SI, rSource2); -#31.Dest,26.Source,21.0b11000010,1,0,11./,4.INDCR::::wrcr r -# do_wrcr (_SD, rDest, rSource1, rSource2); -#31.Dest,26.Source,21.0b11000010,1,1,11./::::wrcr l -# do_wrcr (_SD, rDest, LongSignedImmediate, rSource2); +// wrcr - see swcr, creg, source, r0 // xnor void::function::do_xnor:signed32 *rDest, signed32 Source1, signed32 Source2 *rDest = ~ (Source1 ^ Source2); -31.Dest,26.Source2,21.0b0011001,15.0,14.UnsignedImmediate::::xnor i +31.Dest,26.Source2,21.0b0011001,14.UnsignedImmediate::::xnor i do_xnor (_SD, rDest, vSource1, rSource2); -31.Dest,26.Source2,21.0b110011001,13.0,12.0,11./,4.Source1::::xnor r +31.Dest,26.Source2,21.0b110011001,12.0,11./,4.Source1::::xnor r do_xnor (_SD, rDest, rSource1, rSource2); -31.Dest,26.Source2,21.0b110011001,13.0,12.1,11./::::xnor l +31.Dest,26.Source2,21.0b110011001,12.1,11./::::xnor l long_immediate (LongUnsignedImmediate); do_xnor (_SD, rDest, LongUnsignedImmediate, rSource2); diff --git a/sim/tic80/interp.c b/sim/tic80/interp.c index 5845e06..fe9b98d 100644 --- a/sim/tic80/interp.c +++ b/sim/tic80/interp.c @@ -40,6 +40,7 @@ engine_init (SIM_DESC sd) void engine_error (SIM_DESC sd, + sim_cpu *cpu, instruction_address cia, const char *fmt, ...) @@ -52,7 +53,7 @@ engine_error (SIM_DESC sd, if (sd->halt_ok) { sim_io_printf (sd, "\n"); - engine_halt (sd, cia, sim_signalled, SIGABRT); + engine_halt (sd, cpu, cia, sim_signalled, SIGABRT); } else sim_io_error (sd, " - aborting simulation"); @@ -60,6 +61,7 @@ engine_error (SIM_DESC sd, void engine_halt (SIM_DESC sd, + sim_cpu *cpu, instruction_address cia, enum sim_stop reason, int siggnal) @@ -70,18 +72,20 @@ engine_halt (SIM_DESC sd, sd->siggnal = siggnal; sd->halt_ok = 0; sd->restart_ok = 0; - sd->cpu.cia = cia; + if (cpu != NULL) + cpu->cia = cia; longjmp (sd->path_to_halt, 1); } void engine_restart (SIM_DESC sd, + sim_cpu *cpu, instruction_address cia) { if (!sd->restart_ok) sim_io_error (sd, "engine_restart - bad longjmp"); sd->restart_ok = 0; - sd->cpu.cia = cia; + cpu->cia = cia; longjmp(sd->path_to_restart, 1); } @@ -93,10 +97,11 @@ engine_run_until_stop (SIM_DESC sd, if (!setjmp (sd->path_to_halt)) { instruction_address cia; + sim_cpu *cpu = STATE_CPU (sd, 0); sd->halt_ok = 1; setjmp (sd->path_to_restart); sd->restart_ok = 1; - cia = STATE_CPU (sd, 0)->cia; + cia = cpu->cia; do { if (cia.ip == -1) @@ -112,6 +117,6 @@ engine_run_until_stop (SIM_DESC sd, } } while (*keep_running); - engine_halt (sd, cia, sim_stopped, SIGINT); + engine_halt (sd, cpu, cia, sim_stopped, SIGINT); } } diff --git a/sim/tic80/sim-calls.c b/sim/tic80/sim-calls.c index b85480e..b86c826 100644 --- a/sim/tic80/sim-calls.c +++ b/sim/tic80/sim-calls.c @@ -142,8 +142,8 @@ sim_kill (SIM_DESC sd) int sim_read (SIM_DESC sd, SIM_ADDR mem, unsigned char *buf, int length) { - sim_io_error (sd, "sim_read"); - return 0; + return sim_core_read_buffer (sd, sim_core_write_map, + buf, mem, length); } @@ -155,17 +155,50 @@ sim_write (SIM_DESC sd, SIM_ADDR mem, unsigned char *buf, int length) } +/* FIXME - these magic numbers need to be moved elsewhere */ + +#define SP_REGNUM 1 /* Contains address of top of stack */ +#define FP_REGNUM 31 /* Contains address of executing stack frame */ +#define PC_REGNUM 32 /* Contains program counter (FIXME?) */ +#define NPC_REGNUM 33 /* Contains the next program counter (FIXME?) */ +#define A0_REGNUM 34 /* Accumulator register 0 */ +#define A3_REGNUM 37 /* Accumulator register 1 */ + +#define R0_REGNUM 0 /* General Purpose Register 0 - for sim */ +#define Rn_REGNUM 31 /* Last General Purpose Register - for sim */ +#define An_REGNUM A3_REGNUM /* Last Accumulator register - for sim */ + void -sim_fetch_register (SIM_DESC sd, int regno, unsigned char *buf) +sim_fetch_register (SIM_DESC sd, int regnr, unsigned char *buf) { - sim_io_error (sd, "sim_fetch_register"); + if (regnr >= R0_REGNUM && regnr <= Rn_REGNUM) + *(unsigned32*)buf = H2T_4 (STATE_CPU (sd, 0)->reg[regnr - A0_REGNUM]); + else if (regnr == PC_REGNUM) + *(unsigned32*)buf = H2T_4 (STATE_CPU (sd, 0)->cia.ip); + else if (regnr == NPC_REGNUM) + *(unsigned32*)buf = H2T_4 (STATE_CPU (sd, 0)->cia.dp); + else if (regnr >= A0_REGNUM && regnr <= An_REGNUM) + *(unsigned64*)buf = H2T_8 (STATE_CPU (sd, 0)->acc[regnr - A0_REGNUM]); + else + sim_io_error (sd, "sim_fetch_register - unknown register nr %d", regnr); + return; } void -sim_store_register (SIM_DESC sd, int regno, unsigned char *buf) +sim_store_register (SIM_DESC sd, int regnr, unsigned char *buf) { - sim_io_error (sd, "sim_info"); + if (regnr >= R0_REGNUM && regnr <= Rn_REGNUM) + STATE_CPU (sd, 0)->reg[regnr - A0_REGNUM] = T2H_4 (*(unsigned32*)buf); + else if (regnr == PC_REGNUM) + STATE_CPU (sd, 0)->cia.ip = T2H_4 (*(unsigned32*)buf); + else if (regnr == NPC_REGNUM) + STATE_CPU (sd, 0)->cia.dp = T2H_4 (*(unsigned32*)buf); + else if (regnr == A0_REGNUM && regnr <= An_REGNUM) + STATE_CPU (sd, 0)->acc[regnr - A0_REGNUM] = H2T_8 (*(unsigned64*)buf); + else + sim_io_error (sd, "sim_fetch_register - unknown register nr %d", regnr); + return; } diff --git a/sim/tic80/sim-main.h b/sim/tic80/sim-main.h index 2f726f6..a01ad42 100644 --- a/sim/tic80/sim-main.h +++ b/sim/tic80/sim-main.h @@ -75,27 +75,31 @@ extern void engine_init (SIM_DESC sd); -/* Mechanisms for stopping/restarting the simulation */ +/* Mechanisms for stopping/restarting the simulation. + + A non NULL CPU argument designates the processor that is initiating + the halt. After the simulation has stopped that processor should + be marked as the last one active */ extern void engine_error (SIM_DESC sd, + sim_cpu *cpu, instruction_address cia, const char *fmt, ...); extern void engine_halt (SIM_DESC sd, + sim_cpu *cpu, instruction_address cia, enum sim_stop reason, int siggnal); extern void engine_restart (SIM_DESC sd, + sim_cpu *cpu, instruction_address cia); - - - /* SIMULATE INSTRUCTIONS, various different ways of achieving the same thing (others later) */ -- 2.7.4