/[gxemul]/trunk/src/cpus/cpu_m88k_instr.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk/src/cpus/cpu_m88k_instr.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 43 by dpavlin, Mon Oct 8 16:22:32 2007 UTC revision 44 by dpavlin, Mon Oct 8 16:22:56 2007 UTC
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: cpu_m88k_instr.c,v 1.33 2007/06/05 06:41:30 debug Exp $   *  $Id: cpu_m88k_instr.c,v 1.42 2007/06/28 13:36:46 debug Exp $
29   *   *
30   *  M88K instructions.   *  M88K instructions.
31   *   *
# Line 58  X(nop) Line 58  X(nop)
58   *  bsr_samepage:   Branch to subroutine (to within the same translated page)   *  bsr_samepage:   Branch to subroutine (to within the same translated page)
59   *   *
60   *  arg[0] = pointer to new instr_call   *  arg[0] = pointer to new instr_call
61     *  arg[2] = offset to return address, from start of page
62   */   */
63  X(br_samepage)  X(br_samepage)
64  {  {
# Line 65  X(br_samepage) Line 66  X(br_samepage)
66  }  }
67  X(bsr_samepage)  X(bsr_samepage)
68  {  {
69          SYNCH_PC;          cpu->cd.m88k.r[M88K_RETURN_REG] = (cpu->pc &
70          cpu->cd.m88k.r[M88K_RETURN_REG] = cpu->pc + sizeof(uint32_t);              ~((M88K_IC_ENTRIES_PER_PAGE-1) << M88K_INSTR_ALIGNMENT_SHIFT))
71                + ic->arg[2];
72          cpu->cd.m88k.next_ic = (struct m88k_instr_call *) ic->arg[0];          cpu->cd.m88k.next_ic = (struct m88k_instr_call *) ic->arg[0];
73  }  }
74    
# Line 78  X(bsr_samepage) Line 80  X(bsr_samepage)
80   *  bsr.n: Branch to subroutine (to a different page) with delay slot   *  bsr.n: Branch to subroutine (to a different page) with delay slot
81   *   *
82   *  arg[1] = relative offset from start of page   *  arg[1] = relative offset from start of page
83     *  arg[2] = offset to return address, from start of page
84   */   */
85  X(br)  X(br)
86  {  {
# Line 101  X(br_n) Line 104  X(br_n)
104  }  }
105  X(bsr)  X(bsr)
106  {  {
107          SYNCH_PC;          cpu->pc &= ~((M88K_IC_ENTRIES_PER_PAGE-1) <<
108          cpu->cd.m88k.r[M88K_RETURN_REG] = cpu->pc + sizeof(uint32_t);              M88K_INSTR_ALIGNMENT_SHIFT);
109          cpu->pc = (uint32_t)((cpu->pc & 0xfffff000) + (int32_t)ic->arg[1]);          cpu->cd.m88k.r[M88K_RETURN_REG] = cpu->pc + ic->arg[2];
110            cpu->pc = (uint32_t) (cpu->pc + ic->arg[1]);
111          quick_pc_to_pointers(cpu);          quick_pc_to_pointers(cpu);
112  }  }
113  X(bsr_n)  X(bsr_n)
114  {  {
115          cpu->cd.m88k.delay_target = (cpu->pc & ~((M88K_IC_ENTRIES_PER_PAGE-1) <<          cpu->pc &= ~((M88K_IC_ENTRIES_PER_PAGE-1) <<
116              M88K_INSTR_ALIGNMENT_SHIFT)) + (int32_t)ic->arg[1];              M88K_INSTR_ALIGNMENT_SHIFT);
117          SYNCH_PC;          cpu->cd.m88k.r[M88K_RETURN_REG] = cpu->pc + ic->arg[2] + 4;
118          cpu->cd.m88k.r[M88K_RETURN_REG] = cpu->pc + sizeof(uint32_t) * 2;          cpu->cd.m88k.delay_target = cpu->pc + ic->arg[1];
119          cpu->delay_slot = TO_BE_DELAYED;          cpu->delay_slot = TO_BE_DELAYED;
120          ic[1].f(cpu, ic+1);          ic[1].f(cpu, ic+1);
121          cpu->n_translated_instrs ++;          cpu->n_translated_instrs ++;
# Line 125  X(bsr_n) Line 129  X(bsr_n)
129  }  }
130  X(bsr_trace)  X(bsr_trace)
131  {  {
132          SYNCH_PC;          cpu->pc &= ~((M88K_IC_ENTRIES_PER_PAGE-1) <<
133          cpu->cd.m88k.r[M88K_RETURN_REG] = cpu->pc + sizeof(uint32_t);              M88K_INSTR_ALIGNMENT_SHIFT);
134          cpu->pc = (uint32_t)((cpu->pc & 0xfffff000) + (int32_t)ic->arg[1]);          cpu->cd.m88k.r[M88K_RETURN_REG] = cpu->pc + ic->arg[2];
135            cpu->pc = (uint32_t) (cpu->pc + ic->arg[1]);
136          cpu_functioncall_trace(cpu, cpu->pc);          cpu_functioncall_trace(cpu, cpu->pc);
137          quick_pc_to_pointers(cpu);          quick_pc_to_pointers(cpu);
138  }  }
139  X(bsr_n_trace)  X(bsr_n_trace)
140  {  {
141          cpu->cd.m88k.delay_target = (cpu->pc & ~((M88K_IC_ENTRIES_PER_PAGE-1) <<          cpu->pc &= ~((M88K_IC_ENTRIES_PER_PAGE-1) <<
142              M88K_INSTR_ALIGNMENT_SHIFT)) + (int32_t)ic->arg[1];              M88K_INSTR_ALIGNMENT_SHIFT);
143          SYNCH_PC;          cpu->cd.m88k.r[M88K_RETURN_REG] = cpu->pc + ic->arg[2] + 4;
144          cpu->cd.m88k.r[M88K_RETURN_REG] = cpu->pc + sizeof(uint32_t) * 2;          cpu->cd.m88k.delay_target = cpu->pc + ic->arg[1];
145          cpu->delay_slot = TO_BE_DELAYED;          cpu->delay_slot = TO_BE_DELAYED;
146          ic[1].f(cpu, ic+1);          ic[1].f(cpu, ic+1);
147          cpu->n_translated_instrs ++;          cpu->n_translated_instrs ++;
# Line 174  X(bb0_samepage) Line 179  X(bb0_samepage)
179  }  }
180  X(bb0_n)  X(bb0_n)
181  {  {
182          int cond = !(reg(ic->arg[0]) & ic->arg[1]);          int cond = !(reg(ic->arg[0]) & (uint32_t)ic->arg[1]);
183          cpu->cd.m88k.delay_target = (cpu->pc & ~((M88K_IC_ENTRIES_PER_PAGE-1) <<          cpu->cd.m88k.delay_target = (cpu->pc & ~((M88K_IC_ENTRIES_PER_PAGE-1) <<
184              M88K_INSTR_ALIGNMENT_SHIFT)) + (int32_t)ic->arg[2];              M88K_INSTR_ALIGNMENT_SHIFT)) + (int32_t)ic->arg[2];
185          cpu->delay_slot = TO_BE_DELAYED;          cpu->delay_slot = TO_BE_DELAYED;
# Line 479  X(mak) Line 484  X(mak)
484  X(clr)  X(clr)
485  {  {
486          int w = (reg(ic->arg[2]) >> 5) & 0x1f, o = reg(ic->arg[2]) & 0x1f;          int w = (reg(ic->arg[2]) >> 5) & 0x1f, o = reg(ic->arg[2]) & 0x1f;
487          uint32_t x = w == 0? 0xffffffff : (1 << w) - 1;          uint32_t x = w == 0? 0xffffffff : ((uint32_t)1 << w) - 1;
488          x <<= o;          x <<= o;
489          reg(ic->arg[0]) = reg(ic->arg[1]) & ~x;          reg(ic->arg[0]) = reg(ic->arg[1]) & ~x;
490  }  }
491  X(set)  X(set)
492  {  {
493          int w = (reg(ic->arg[2]) >> 5) & 0x1f, o = reg(ic->arg[2]) & 0x1f;          int w = (reg(ic->arg[2]) >> 5) & 0x1f, o = reg(ic->arg[2]) & 0x1f;
494          uint32_t x = w == 0? 0xffffffff : (1 << w) - 1;          uint32_t x = w == 0? 0xffffffff : ((uint32_t)1 << w) - 1;
495          x <<= o;          x <<= o;
496          reg(ic->arg[0]) = reg(ic->arg[1]) | x;          reg(ic->arg[0]) = reg(ic->arg[1]) | x;
497  }  }
# Line 769  X(rte) Line 774  X(rte)
774          m88k_stcr(cpu, cpu->cd.m88k.cr[M88K_CR_EPSR], M88K_CR_PSR, 1);          m88k_stcr(cpu, cpu->cd.m88k.cr[M88K_CR_EPSR], M88K_CR_PSR, 1);
775    
776          /*  First try the NIP, if it is Valid:  */          /*  First try the NIP, if it is Valid:  */
777          if (cpu->cd.m88k.cr[M88K_CR_SNIP] & M88K_NIP_V) {          cpu->pc = cpu->cd.m88k.cr[M88K_CR_SNIP] & M88K_NIP_ADDR;
778                  cpu->pc = cpu->cd.m88k.cr[M88K_CR_SNIP] & M88K_NIP_ADDR;          if (cpu->cd.m88k.cr[M88K_CR_SNIP] & M88K_NIP_E) {
779                  if (cpu->cd.m88k.cr[M88K_CR_SNIP] & M88K_NIP_E) {                  fatal("rte: NIP: TODO: single-step support\n");
780                          fatal("rte: NIP: TODO: single-step support\n");                  goto abort_dump;
                         goto abort_dump;  
                 }  
         } else {  
                 /*  The FIP must be valid...  */  
                 if (!(cpu->cd.m88k.cr[M88K_CR_SFIP] & M88K_NIP_V)) {  
                         fatal("rte: neither FIP nor NIP valid? TODO\n");  
                         goto abort_dump;  
                 }  
                 cpu->pc = cpu->cd.m88k.cr[M88K_CR_SFIP] & M88K_FIP_ADDR;  
781          }          }
782    
783          if (cpu->cd.m88k.cr[M88K_CR_SFIP] & M88K_FIP_E) {          if (cpu->cd.m88k.cr[M88K_CR_SFIP] & M88K_FIP_E) {
# Line 789  X(rte) Line 785  X(rte)
785                  goto abort_dump;                  goto abort_dump;
786          }          }
787    
788          if (cpu->cd.m88k.cr[M88K_CR_SNIP] & M88K_FIP_V &&          if ((cpu->cd.m88k.cr[M88K_CR_SFIP] & M88K_FIP_ADDR)
789              cpu->cd.m88k.cr[M88K_CR_SFIP] & M88K_FIP_V &&              == (cpu->cd.m88k.cr[M88K_CR_SNIP] & M88K_NIP_ADDR)) {
790              (cpu->cd.m88k.cr[M88K_CR_SFIP] & M88K_FIP_ADDR)                  cpu->cd.m88k.cr[M88K_CR_SFIP] = cpu->pc + 4;
791            }
792    
793            if ((cpu->cd.m88k.cr[M88K_CR_SFIP] & M88K_FIP_ADDR)
794              != (cpu->cd.m88k.cr[M88K_CR_SNIP] & M88K_NIP_ADDR) + 4) {              != (cpu->cd.m88k.cr[M88K_CR_SNIP] & M88K_NIP_ADDR) + 4) {
795                  /*                  /*
796                   *  The NIP instruction should first be executed (this                   *  The NIP instruction should first be executed (this
# Line 1025  X(end_of_page2) Line 1024  X(end_of_page2)
1024              << M88K_INSTR_ALIGNMENT_SHIFT);              << M88K_INSTR_ALIGNMENT_SHIFT);
1025          cpu->pc += (low_pc << M88K_INSTR_ALIGNMENT_SHIFT);          cpu->pc += (low_pc << M88K_INSTR_ALIGNMENT_SHIFT);
1026    
1027            if (low_pc < 0 || low_pc > ((M88K_IC_ENTRIES_PER_PAGE+1)
1028                << M88K_INSTR_ALIGNMENT_SHIFT)) {
1029                    printf("[ end_of_page2: HUH? low_pc=%i, cpu->pc = %08"
1030                        PRIx32" ]\n", low_pc, (uint32_t) cpu->pc);
1031            }
1032    
1033          /*  This doesn't count as an executed instruction.  */          /*  This doesn't count as an executed instruction.  */
1034          cpu->n_translated_instrs --;          cpu->n_translated_instrs --;
1035    
# Line 1313  X(to_be_translated) Line 1318  X(to_be_translated)
1318                  ic->arg[0] = (size_t) ( cpu->cd.m88k.cur_ic_page +                  ic->arg[0] = (size_t) ( cpu->cd.m88k.cur_ic_page +
1319                      (offset >> M88K_INSTR_ALIGNMENT_SHIFT) );                      (offset >> M88K_INSTR_ALIGNMENT_SHIFT) );
1320                  ic->arg[1] = offset;                  ic->arg[1] = offset;
1321                    ic->arg[2] = (addr & 0xffc) + 4;    /*  Return offset
1322                                                            for bsr_samepage  */
1323    
1324                  if (offset >= 0 && offset <= 0xffc &&                  if (offset >= 0 && offset <= 0xffc &&
1325                      samepage_function != NULL)                      samepage_function != NULL)
# Line 1401  X(to_be_translated) Line 1408  X(to_be_translated)
1408                                          int w = ic->arg[2] >> 5;                                          int w = ic->arg[2] >> 5;
1409                                          int o = ic->arg[2] & 0x1f;                                          int o = ic->arg[2] & 0x1f;
1410                                          uint32_t x = w == 0? 0xffffffff                                          uint32_t x = w == 0? 0xffffffff
1411                                              : (1 << w) - 1;                                              : ((uint32_t)1 << w) - 1;
1412                                          x <<= o;                                          x <<= o;
1413                                          ic->arg[2] = ~x;                                          ic->arg[2] = ~x;
1414                                     }                                     }
# Line 1411  X(to_be_translated) Line 1418  X(to_be_translated)
1418                                          int w = ic->arg[2] >> 5;                                          int w = ic->arg[2] >> 5;
1419                                          int o = ic->arg[2] & 0x1f;                                          int o = ic->arg[2] & 0x1f;
1420                                          uint32_t x = w == 0? 0xffffffff                                          uint32_t x = w == 0? 0xffffffff
1421                                              : (1 << w) - 1;                                              : ((uint32_t)1 << w) - 1;
1422                                          x <<= o;                                          x <<= o;
1423                                          ic->arg[2] = x;                                          ic->arg[2] = x;
1424                                     }                                     }

Legend:
Removed from v.43  
changed lines
  Added in v.44

  ViewVC Help
Powered by ViewVC 1.1.26