I960_CPUComponent.cc Source File

Back to the index.

I960_CPUComponent.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2018-2019 Anders Gavare. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * 3. The name of the author may not be used to endorse or promote products
13  * derived from this software without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 
28 #include <assert.h>
29 #include <stdio.h>
30 #include <string.h>
31 #include <iomanip>
32 
33 #include "ComponentFactory.h"
34 #include "GXemul.h"
36 
37 
39  int opcode;
40  const char* mnemonic;
41  bool has_src1;
42  bool has_src2;
43  bool has_dst;
44  bool has_src3; // true if the dst/src field is used as a source
45 };
46 
48  { 0x580, "notbit", true, true, true, false },
49  { 0x581, "and", true, true, true, false },
50  { 0x582, "andnot", true, true, true, false },
51  { 0x583, "setbit", true, true, true, false },
52  { 0x584, "notand", true, true, true, false },
53  { 0x586, "xor", true, true, true, false },
54  { 0x587, "or", true, true, true, false },
55  { 0x588, "nor", true, true, true, false },
56  { 0x589, "xnor", true, true, true, false },
57  { 0x58a, "not", true, false, true, false },
58  { 0x58b, "ornot", true, true, true, false },
59  { 0x58c, "clrbit", true, true, true, false },
60  { 0x58d, "notor", true, true, true, false },
61  { 0x58e, "nand", true, true, true, false },
62  { 0x58f, "alterbit", true, true, true, false },
63 
64  { 0x590, "addo", true, true, true, false },
65  { 0x591, "addi", true, true, true, false },
66  { 0x592, "subo", true, true, true, false },
67  { 0x593, "subi", true, true, true, false },
68  { 0x598, "shro", true, true, true, false },
69  { 0x59a, "shrdi", true, true, true, false },
70  { 0x59b, "shri" , true, true, true, false },
71  { 0x59c, "shlo", true, true, true, false },
72  { 0x59d, "rotate", true, true, true, false },
73  { 0x59e, "shli", true, true, true, false },
74 
75  { 0x5a0, "cmpo", true, true, false, false },
76  { 0x5a1, "cmpi", true, true, false, false },
77  { 0x5a2, "concmpo", true, true, false, false },
78  { 0x5a3, "concmpi", true, true, false, false },
79  { 0x5a4, "cmpinco", true, true, true, false },
80  { 0x5a5, "cmpinci", true, true, true, false },
81  { 0x5a6, "cmpdeco", true, true, true, false },
82  { 0x5a7, "cmpdeci", true, true, true, false },
83 
84  { 0x5ac, "scanbyte", true, true, false, false },
85  { 0x5ae, "chkbit", true, true, false, false },
86 
87  { 0x5b0, "addc", true, true, true, false },
88  { 0x5b2, "subc", true, true, true, false },
89 
90  { 0x5cc, "mov", true, false, true, false },
91  { 0x5d8, "eshro", true, true, true, false },
92  { 0x5dc, "movl", true, false, true, false },
93  { 0x5ec, "movt", true, false, true, false },
94  { 0x5fc, "movq", true, false, true, false },
95 
96  { 0x630, "sdma", true, true, true, true },
97  { 0x631, "udma", false, false, false, false },
98 
99  { 0x640, "spanbit", true, false, true, false },
100  { 0x641, "scanbit", true, false, true, false },
101  { 0x645, "modac", true, true, true, true },
102 
103  { 0x650, "modify", true, true, true, true },
104  { 0x651, "extract", true, true, true, true },
105  { 0x654, "modtc", true, true, true, true },
106  { 0x655, "modpc", true, true, true, true },
107  { 0x659, "sysctl", true, true, true, true },
108 
109  { 0x660, "calls", true, false, false, false },
110  { 0x66b, "mark", false, false, false, false },
111  { 0x66c, "fmark", false, false, false, false },
112  { 0x66d, "flushreg", false, false, false, false },
113  { 0x66f, "syncf", false, false, false, false },
114 
115  { 0x670, "emul", true, true, true, false },
116  { 0x671, "ediv", true, true, true, false },
117 
118  { 0x701, "mulo", true, true, true, false },
119  { 0x708, "remo", true, true, true, false },
120  { 0x70b, "divo", true, true, true, false },
121 
122  { 0x741, "muli", true, true, true, false },
123  { 0x748, "remi", true, true, true, false },
124  { 0x749, "modi", true, true, true, false },
125  { 0x74b, "divi", true, true, true, false },
126 
127  { 0, NULL, false, false, false, false }
128 };
129 
130 
132  : CPUDyntransComponent("i960_cpu", "i960")
133 {
134  m_frequency = 25e6;
135  m_isBigEndian = false;
136  m_model = "i960CA";
137 
138  ResetState();
139 
140  AddVariable("model", &m_model);
141 
142  for (size_t i = 0; i < N_I960_REGS; i++) {
143  AddVariable(i960_regnames[i], &m_r[i]);
144  }
145 
146  for (size_t i = 0; i < N_I960_SFRS; i++) {
147  stringstream ss;
148  ss << "sfr" << i;
149  AddVariable(ss.str(), &m_sfr[i]);
150  }
151 
152  AddVariable("i960_ac", &m_i960_ac);
153  AddVariable("i960_pc", &m_i960_pc);
154  AddVariable("i960_tc", &m_i960_tc);
155  AddVariable("nr_of_valid_sfrs", &m_nr_of_valid_sfrs);
156 }
157 
158 
160 {
161  // Defaults:
163  settings["model"] = "i960CA";
164 
166  return NULL;
167 
169  if (!cpu->SetVariableValue("model", "\"" + settings["model"] + "\""))
170  return NULL;
171 
172  return cpu;
173 }
174 
175 
176 static string regname_or_literal(int reg, int m, int s)
177 {
178  // Regular g or r registers
179  if (m == 0 && s == 0)
180  return i960_regnames[reg];
181 
182  stringstream ss;
183 
184  if (m != 0 && s == 0) {
185  // Literal
186  ss << reg;
187  } else if (m == 0 && s != 0) {
188  // Special Function Register
189  ss << "sfr" << reg;
190  } else {
191  ss << "reserved" << reg;
192  }
193 
194  return ss.str();
195 }
196 
197 
199 {
200  m_pageSize = 4096;
201 
202  for (size_t i=0; i<N_I960_REGS; i++)
203  m_r[i] = 0;
204 
205  for (size_t i=0; i<N_I960_SFRS; i++)
206  m_sfr[i] = 0;
207 
208  m_pc = 0;
209 
210  m_i960_ac = 0;
211  m_i960_pc = 0;
212  m_i960_tc = 0;
213 
214  // 0 for most (?) i960 implementations. 3 for i960CA. (TODO: CF etc)
215  m_nr_of_valid_sfrs = 0;
216  if (m_model == "i960CA")
217  m_nr_of_valid_sfrs = 3;
218 
220 }
221 
222 
224 {
225  if (m_pc & 0x3) {
226  gxemul->GetUI()->ShowDebugMessage(this, "the pc register"
227  " can not have bit 0 or 1 set!\n");
228  return false;
229  }
230 
232 }
233 
234 
235 bool I960_CPUComponent::CheckVariableWrite(StateVariable& var, const string& oldValue)
236 {
237  // UI* ui = GetUI();
238 
239  return CPUDyntransComponent::CheckVariableWrite(var, oldValue);
240 }
241 
242 
243 void I960_CPUComponent::ShowRegisters(GXemul* gxemul, const vector<string>& arguments) const
244 {
245  stringstream ss;
246 
247  ss.flags(std::ios::hex);
248  ss << " ip = 0x" << std::setfill('0') << std::setw(8) << (uint32_t)m_pc;
249 
250  string symbol = GetSymbolRegistry().LookupAddress(m_pc, true);
251  if (symbol != "")
252  ss << " <" << symbol << ">";
253  ss << "\n";
254 
255  for (size_t i = 0; i < N_I960_REGS; i++) {
256  ss << std::setfill(' ') << std::setw(4) << i960_regnames[i]
257  << " = 0x" << std::setfill('0') << std::setw(8) << m_r[i];
258  if ((i&3) == 3)
259  ss << "\n";
260  else
261  ss << " ";
262  }
263 
264  for (size_t i = 0; i < m_nr_of_valid_sfrs; i++) {
265  stringstream name;
266  name << "sfr" << i;
267  ss << std::setfill(' ') << std::setw(6) << name.str()
268  << " = 0x" << std::setfill('0') << std::setw(8) << m_sfr[i];
269  if ((i&3) == 3)
270  ss << "\n";
271  else
272  ss << " ";
273  }
274 
275  gxemul->GetUI()->ShowDebugMessage(ss.str());
276 }
277 
278 
280 {
281  return 8;
282 }
283 
284 
286 {
287  return m_r[I960_G0 + n];
288 }
289 
290 
292 {
293  retval = m_r[I960_G0];
294  return true;
295 }
296 
297 
299 {
300  // 4 bytes per instruction means 2 bits shift.
301  return 2;
302 }
303 
304 
306 {
307  return instr_ToBeTranslated;
308 }
309 
310 
311 bool I960_CPUComponent::VirtualToPhysical(uint64_t vaddr, uint64_t& paddr,
312  bool& writable)
313 {
314  paddr = vaddr;
315  writable = true;
316  return true;
317 }
318 
319 
321 {
322  return pc;
323 }
324 
325 
326 size_t I960_CPUComponent::DisassembleInstruction(uint64_t vaddr, vector<string>& result)
327 {
328  size_t instrSize = sizeof(uint32_t);
329  uint32_t instructionWord;
330 
331  // Read the instruction word:
332  AddressSelect(vaddr);
333  bool readOk = ReadData(instructionWord, m_isBigEndian? BigEndian : LittleEndian);
334  if (!readOk)
335  return 0;
336 
337  const uint32_t iword = instructionWord;
338 
339  const int opcode = iword >> 24;
340 
341  const int REG_src_dst = (iword >> 19) & 0x1f;
342  const int REG_src2 = (iword >> 14) & 0x1f;
343  const int REG_m3 = (iword >> 13) & 0x1;
344  const int REG_m2 = (iword >> 12) & 0x1;
345  const int REG_m1 = (iword >> 11) & 0x1;
346  const int REG_opcode2 = (iword >> 7) & 0xf;
347  const int REG_sfr2 = (iword >> 6) & 0x1;
348  const int REG_sfr1 = (iword >> 5) & 0x1;
349  const int REG_src1 = (iword >> 0) & 0x1f;
350 
351  const int COBR_src_dst = (iword >> 19) & 0x1f;
352  const int COBR_src_2 = (iword >> 14) & 0x1f;
353  const int COBR_m1 = (iword >> 13) & 0x1;
354  const int COBR_disp = (iword >> 2) & 0x7ff;
355  const int COBR_t = (iword >> 1) & 0x1;
356  const int COBR_s2 = (iword >> 0) & 0x1;
357 
358  const int CTRL_disp = (iword >> 2) & 0x3fffff;
359  const int CTRL_t = (iword >> 1) & 0x1;
360 
361  // const int MEMA_src_dst = (iword >> 19) & 0x1f; Same as MEMB_src_dst
362  const int MEMA_abase = (iword >> 14) & 0x1f;
363  const int MEMA_md = (iword >> 13) & 0x1;
364  // const int MEMA_zero = (iword >> 12) & 0x1; 0 for MEMA, 1 for MEMB
365  const int MEMA_offset = (iword >> 0) & 0xfff;
366 
367  const int MEMB_src_dst = (iword >> 19) & 0x1f;
368  const int MEMB_abase = (iword >> 14) & 0x1f;
369  const int MEMB_mode = (iword >> 10) & 0xf;
370  const int MEMB_scale = (iword >> 7) & 0x7;
371  // const int MEMB_sfr = (iword >> 5) & 0x3; Should be 00?
372  const int MEMB_index = (iword >> 0) & 0x1f;
373 
374  bool hasDisplacementWord = false;
375 
376  if (opcode >= 0x80 && iword & 0x1000) {
377  /* Only some MEMB instructions have displacement words: */
378  int mode = (iword >> 10) & 0xf;
379  if (mode == 0x5 || mode >= 0xc)
380  hasDisplacementWord = true;
381  }
382 
383  uint32_t displacementWord = 0;
384  if (hasDisplacementWord) {
385  instrSize += sizeof(uint32_t);
386 
387  // Read the displacement word:
388  AddressSelect(vaddr + sizeof(uint32_t));
389  readOk = ReadData(displacementWord, m_isBigEndian? BigEndian : LittleEndian);
390 
391  if (!readOk)
392  return 0;
393  }
394 
395  stringstream ssHex;
396  ssHex.flags(std::ios::hex);
397  ssHex << std::setfill('0') << std::setw(8) << (uint32_t) iword;
398  if (hasDisplacementWord)
399  ssHex << " " << std::setfill('0') << std::setw(8) << (uint32_t) displacementWord;
400  else
401  ssHex << " ";
402 
403  result.push_back(ssHex.str());
404 
405 
406  stringstream ssOpcode;
407  stringstream ssArgs;
408  stringstream ssComments;
409 
410  if (opcode >= 0x08 && opcode <= 0x1f) {
411  /* CTRL: */
412  const char* mnemonics[] = {
413  "b", /* 0x08 */
414  "call", /* 0x09 */
415  "ret", /* 0x0a */
416  "bal", /* 0x0b */
417  "unknown_ctrl_0x0c", /* 0x0c */
418  "unknown_ctrl_0x0d", /* 0x0d */
419  "unknown_ctrl_0x0e", /* 0x0e */
420  "unknown_ctrl_0x0f", /* 0x0f */
421  "bno", /* 0x10 */
422  "bg", /* 0x11 */
423  "be", /* 0x12 */
424  "bge", /* 0x13 */
425  "bl", /* 0x14 */
426  "bne", /* 0x15 */
427  "ble", /* 0x16 */
428  "bo", /* 0x17 */
429  "faultno", /* 0x18 */
430  "faultg", /* 0x19 */
431  "faulte", /* 0x1a */
432  "faultge", /* 0x1b */
433  "faultl", /* 0x1c */
434  "faultne", /* 0x1d */
435  "faultle", /* 0x1e */
436  "faulto" /* 0x1f */
437  };
438 
439  ssOpcode << mnemonics[opcode - 0x08];
440  if (CTRL_t)
441  ssOpcode << ".f";
442 
443  bool hasDisplacement = opcode < 0x18 && opcode != 0x0a;
444  if (hasDisplacement) {
445  uint32_t disp = CTRL_disp << 2;
446  if (disp & 0x00800000)
447  disp |= 0xff000000;
448 
449  uint32_t addr = vaddr + disp;
450  ssArgs << "0x";
451  ssArgs.flags(std::ios::hex);
452  ssArgs << std::setfill('0') << std::setw(8) << addr;
453  }
454  } else if (opcode >= 0x20 && opcode <= 0x3f) {
455  /* COBR: */
456  const char* mnemonics[] = {
457  "testno", /* 0x20 */
458  "testg", /* 0x21 */
459  "teste", /* 0x22 */
460  "testge", /* 0x23 */
461  "testl", /* 0x24 */
462  "testne", /* 0x25 */
463  "testle", /* 0x26 */
464  "testo", /* 0x27 */
465 
466  "unknown_cobr_0x28", /* 0x28 */
467  "unknown_cobr_0x29", /* 0x29 */
468  "unknown_cobr_0x2a", /* 0x2a */
469  "unknown_cobr_0x2b", /* 0x2b */
470  "unknown_cobr_0x2c", /* 0x2c */
471  "unknown_cobr_0x2d", /* 0x2d */
472  "unknown_cobr_0x2e", /* 0x2e */
473  "unknown_cobr_0x2f", /* 0x2f */
474 
475  "bbc", /* 0x30 */
476  "cmpobg", /* 0x31 */
477  "cmpobe", /* 0x32 */
478  "cmpobge", /* 0x33 */
479  "cmpobl", /* 0x34 */
480  "cmpobne", /* 0x35 */
481  "cmpobne", /* 0x36 */
482  "bbs", /* 0x37 */
483 
484  "cmpibno", /* 0x38 */
485  "cmpibg", /* 0x39 */
486  "cmpibe", /* 0x3a */
487  "cmpibge", /* 0x3b */
488  "cmpibl", /* 0x3c */
489  "cmpibne", /* 0x3d */
490  "cmpible", /* 0x3e */
491  "cmpibo", /* 0x3f */
492  };
493 
494  ssOpcode << mnemonics[opcode - 0x20];
495  if (COBR_t)
496  ssOpcode << ".f";
497 
498  bool src1isBitpos = opcode == 0x30 || opcode == 0x37;
499 
500  if (opcode <= 0x27) {
501  ssArgs << regname_or_literal(COBR_src_dst, 0, COBR_s2);
502  } else {
503  uint32_t targ = COBR_disp << 2;
504  if (targ & 0x00001000)
505  targ |= 0xffffe000;
506  targ += vaddr;
507 
508  ssArgs << regname_or_literal(COBR_src_dst, src1isBitpos ? 1 : COBR_m1, 0) << ",";
509  ssArgs << regname_or_literal(COBR_src_2, 0, COBR_s2) << ",";
510  ssArgs << "0x";
511  ssArgs.flags(std::ios::hex);
512  ssArgs << std::setfill('0') << std::setw(8) << targ;
513  }
514  } else if (opcode >= 0x58 && opcode <= 0x7f) {
515  /* REG: */
516  struct reg_instruction *rinstr = NULL;
517  for (int i = 0; ; ++i) {
518  if (reg_instructions[i].mnemonic == NULL)
519  break;
520  if (reg_instructions[i].opcode == (opcode << 4) + REG_opcode2) {
521  rinstr = &reg_instructions[i];
522  break;
523  }
524  }
525 
526  bool has_src1 = true, has_src2 = true, has_dst = true, has_src3 = false;
527 
528  if (rinstr == NULL) {
529  ssOpcode << "unknown_reg_";
530  ssOpcode.flags(std::ios::hex);
531  ssOpcode << std::setfill('0') << std::setw(2) << opcode;
532  ssOpcode << ":" << std::setw(1) << REG_opcode2;
533  } else {
534  ssOpcode << rinstr->mnemonic;
535  has_src1 = rinstr->has_src1;
536  has_src2 = rinstr->has_src2;
537  has_dst = rinstr->has_dst;
538  has_src3 = rinstr->has_src3;
539  }
540 
541  if (has_src1)
542  ssArgs << regname_or_literal(REG_src1, REG_m1, REG_sfr1);
543 
544  if (has_src2) {
545  if (ssArgs.str().length() > 0)
546  ssArgs << ",";
547  ssArgs << regname_or_literal(REG_src2, REG_m2, REG_sfr2);
548  }
549 
550  if (has_dst) {
551  if (ssArgs.str().length() > 0)
552  ssArgs << ",";
553  if (REG_m3) {
554  /*
555  * The manual for i960CA says (when M3 = 1):
556  *
557  * "src/dst is a literal when used as a source
558  * or a special function register when used
559  * as a destination. M3 may not be 1 when
560  * src/dst is used both as a source and
561  * destination in an instruction (atmod,
562  * modify, extract, modpc)."
563  */
564  if (has_src3)
565  ssArgs << regname_or_literal(REG_src_dst, 1, 0);
566  else
567  ssArgs << regname_or_literal(REG_src_dst, 0, 1);
568  } else
569  ssArgs << regname_or_literal(REG_src_dst, 0, 0);
570  }
571  } else if (opcode >= 0x80 && opcode <= 0xcf) {
572  /* MEM: */
573 
574  /* NOTE: These are for i960CA. When implementing support for
575  other CPU variants, include an enum indicating which CPU
576  it is for so that a warning can be printed for instructions
577  that will cause faults on another CPU. */
578  const char* mnemonics[] = {
579  "ldob", /* 0x80 */
580  "unknown_mem_0x81", /* 0x81 BiiN ldvob */
581  "stob", /* 0x82 */
582  "unknown_mem_0x83", /* 0x83 BiiN stvob */
583  "bx", /* 0x84 */
584  "balx", /* 0x85 */
585  "callx", /* 0x86 */
586  "unknown_mem_0x87", /* 0x87 */
587 
588  "ldos", /* 0x88 */
589  "unknown_mem_0x89", /* 0x89 BiiN ldvos */
590  "stos", /* 0x8a */
591  "unknown_mem_0x8b", /* 0x8b BiiN stvos */
592  "lda", /* 0x8c */
593  "unknown_mem_0x8d", /* 0x8d */
594  "unknown_mem_0x8e", /* 0x8e */
595  "unknown_mem_0x8f", /* 0x8f */
596 
597  "ld", /* 0x90 */
598  "unknown_mem_0x91", /* 0x91 BiiN ldv */
599  "st", /* 0x92 */
600  "unknown_mem_0x93", /* 0x93 Biin stv */
601  "unknown_mem_0x94", /* 0x94 */
602  "unknown_mem_0x95", /* 0x95 */
603  "unknown_mem_0x96", /* 0x96 */
604  "unknown_mem_0x97", /* 0x97 */
605 
606  "ldl", /* 0x98 */
607  "unknown_mem_0x99", /* 0x99 BiiN ldvl */
608  "stl", /* 0x9a */
609  "unknown_mem_0x9b", /* 0x9b BiiN stvl */
610  "unknown_mem_0x9c", /* 0x9c */
611  "unknown_mem_0x9d", /* 0x9d */
612  "unknown_mem_0x9e", /* 0x9e */
613  "unknown_mem_0x9f", /* 0x9f */
614 
615  "ldt", /* 0xa0 */
616  "unknown_mem_0xa1", /* 0xa1 BiiN ldvt */
617  "stt", /* 0xa2 */
618  "unknown_mem_0xa3", /* 0xa3 Biin stvt */
619  "unknown_mem_0xa4", /* 0xa4 */
620  "unknown_mem_0xa5", /* 0xa5 */
621  "unknown_mem_0xa6", /* 0xa6 */
622  "unknown_mem_0xa7", /* 0xa7 */
623 
624  "unknown_mem_0xa8", /* 0xa8 */
625  "unknown_mem_0xa9", /* 0xa9 */
626  "unknown_mem_0xaa", /* 0xaa */
627  "unknown_mem_0xab", /* 0xab */
628  "unknown_mem_0xac", /* 0xac */
629  "unknown_mem_0xad", /* 0xad */
630  "unknown_mem_0xae", /* 0xae */
631  "unknown_mem_0xaf", /* 0xaf */
632 
633  "ldq", /* 0xb0 */
634  "unknown_mem_0xb1", /* 0xb1 BiiN ldvq */
635  "stq", /* 0xb2 */
636  "unknown_mem_0xb3", /* 0xb3 BiiN stvq */
637  "unknown_mem_0xb4", /* 0xb4 */
638  "unknown_mem_0xb5", /* 0xb5 */
639  "unknown_mem_0xb6", /* 0xb6 */
640  "unknown_mem_0xb7", /* 0xb7 */
641 
642  "unknown_mem_0xb8", /* 0xb8 */
643  "unknown_mem_0xb9", /* 0xb9 */
644  "unknown_mem_0xba", /* 0xba */
645  "unknown_mem_0xbb", /* 0xbb */
646  "unknown_mem_0xbc", /* 0xbc */
647  "unknown_mem_0xbd", /* 0xbd */
648  "unknown_mem_0xbe", /* 0xbe */
649  "unknown_mem_0xbf", /* 0xbf */
650 
651  "ldib", /* 0xc0 */
652  "unknown_mem_0xc1", /* 0xc1 BiiN ldvib */
653  "stib", /* 0xc2 */
654  "unknown_mem_0xc3", /* 0xc3 Biin stvib */
655  "unknown_mem_0xc4", /* 0xc4 */
656  "unknown_mem_0xc5", /* 0xc5 */
657  "unknown_mem_0xc6", /* 0xc6 */
658  "unknown_mem_0xc7", /* 0xc7 */
659 
660  "ldis", /* 0xc8 */
661  "unknown_mem_0xc9", /* 0xc9 BiiN ldvis */
662  "stis", /* 0xca */
663  "unknown_mem_0xcb", /* 0xcb BiiN stvis */
664  "unknown_mem_0xcc", /* 0xcc */
665  "unknown_mem_0xcd", /* 0xcd */
666  "unknown_mem_0xce", /* 0xce */
667  "unknown_mem_0xcf", /* 0xcf */
668 
669  /* BiiN:
670  d0 = ldm
671  d1 = ldvm
672  d2 = stm
673  d3 = stvm
674  d8 = ldml
675  d9 = ldvml
676  da = stml
677  db = stvml */
678  };
679 
680  ssOpcode << mnemonics[opcode - 0x80];
681 
682  bool usesDst = opcode != 0x84 && opcode != 0x86;
683  bool isStore = !!(opcode & 2);
684 
685  if (usesDst && isStore) {
686  ssArgs << regname_or_literal(MEMB_src_dst, 0, 0) << ",";
687  }
688 
689  if (iword & 0x1000) {
690  /* MEMB: */
691  int scale = 1 << MEMB_scale;
692  switch (MEMB_mode) {
693  case 0x4:
694  ssArgs << "(" << regname_or_literal(MEMB_abase, 0, 0) << ")";
695  break;
696  case 0x5:
697  {
698  uint32_t offset = displacementWord + 8;
699  ssArgs << "0x";
700  ssArgs.flags(std::ios::hex);
701  ssArgs << std::setfill('0') << std::setw(8) << offset;
702  ssArgs << "(ip)";
703  }
704  break;
705  case 0x7:
706  // (reg1)[reg2 * scale]
707  ssArgs << "(" << regname_or_literal(MEMB_abase, 0, 0) << ")";
708  ssArgs << "[" << regname_or_literal(MEMB_index, 0, 0) << "*" << scale << "]";
709  break;
710  case 0xc:
711  case 0xd:
712  {
713  uint32_t offset = displacementWord;
714  ssArgs << "0x";
715  ssArgs.flags(std::ios::hex);
716  ssArgs << std::setfill('0') << std::setw(8) << offset;
717  if (MEMB_mode == 0xd)
718  ssArgs << "(" << regname_or_literal(MEMB_abase, 0, 0) << ")";
719  }
720  break;
721  case 0xe:
722  case 0xf:
723  {
724  uint32_t offset = displacementWord;
725  ssArgs << "0x";
726  ssArgs.flags(std::ios::hex);
727  ssArgs << std::setfill('0') << std::setw(8) << offset;
728  if (MEMB_mode == 0xf)
729  ssArgs << "(" << regname_or_literal(MEMB_abase, 0, 0) << ")";
730  ssArgs << "[" << regname_or_literal(MEMB_index, 0, 0) << "*" << scale << "]";
731  }
732  break;
733  default:
734  ssArgs << "unimplemented MEMB mode!";
735  }
736  } else {
737  /* MEMA: */
738  ssArgs << "0x";
739  ssArgs.flags(std::ios::hex);
740  ssArgs << std::setfill('0') << std::setw(1) << MEMA_offset;
741 
742  if (MEMA_md)
743  ssArgs << "(" << regname_or_literal(MEMA_abase, 0, 0) << ")";
744  }
745 
746  if (usesDst && !isStore) {
747  ssArgs << "," << regname_or_literal(MEMB_src_dst, 0, 0);
748  }
749  } else if (iword == 0) {
750  ssOpcode << "--";
751  } else {
752  ssOpcode << "unknown_0x";
753  ssOpcode.flags(std::ios::hex);
754  ssOpcode << std::setfill('0') << std::setw(2) << (int)opcode;
755  }
756 
757  result.push_back(ssOpcode.str());
758  result.push_back(ssArgs.str());
759  string comments = ssComments.str();
760  if (comments.length() > 0)
761  result.push_back(comments);
762 
763  return instrSize;
764 }
765 
766 
767 string I960_CPUComponent::GetAttribute(const string& attributeName)
768 {
769  if (attributeName == "description")
770  return "Intel i960 processor.";
771 
772  return Component::GetAttribute(attributeName);
773 }
774 
775 
776 /*****************************************************************************/
777 
778 
780 {
782  cpu->m_pc = ic->arg[0].u32;
783  cpu->DyntransPCtoPointers();
784 }
785 
786 
788 {
790  REG32(ic->arg[2]) = ic->arg[0].u32;
791  cpu->m_nextIC = ic + 2;
792 }
793 
794 
796 {
797  REG32(ic->arg[2]) = ic->arg[0].u32;
798 }
799 
800 
802 {
803  REG32(ic->arg[2]) = REG32(ic->arg[0]);
804 }
805 
806 
808 {
810 
811  uint32_t message = REG32(ic->arg[0]);
812  int type = (message >> 8) & 0xff;
813  int field1 = message & 0xff;
814 
815  // type 0 = software interrupt, src1 = vector number
816  // type 1 = invalidate cache
817  // type 2 = configure cache, src1 = cache mode configuration, src2 = cache load address
818  // type 3 = reinitialize, src2 = first-IP, src3 = PRCB address
819  // type 4 = load control register, src1 = register group number
820 
821  if (type == 0x01) {
822  // Invalidate cache.
823  // Right now in GXemul, this is a NOP.
824  UI* ui = cpu->GetUI();
825  ui->ShowDebugMessage(cpu, "invalidating cache (no-op for now)");
826  } else if (type == 0x04) {
827  // Load control register.
828  // TODO.
829  UI* ui = cpu->GetUI();
830  stringstream ss;
831  ss << "TODO: load control register, group " << field1;
832  ui->ShowDebugMessage(cpu, ss.str());
833  } else {
834  stringstream ss;
835 
836  // We didn't actually do anything in this instruction.
837  cpu->m_executedCycles --;
838 
839  // Point to this instruction...
841 
842  // ... and then abort.
843  cpu->m_nextIC = &cpu->m_abortIC;
844 
845  UI* ui = cpu->GetUI();
846  ss << "unimplemented sysctl message type " << type;
847  ui->ShowDebugMessage(cpu, ss.str());
848  }
849 }
850 
851 
852 /*****************************************************************************/
853 
854 
855 void I960_CPUComponent::Translate(uint32_t iword, uint32_t iword2, struct DyntransIC* ic)
856 {
857  UI* ui = GetUI(); // for debug messages
858 
859  unsigned int opcode = iword >> 24;
860 
861  if (opcode >= 0x08 && opcode <= 0x1f) {
862  /* CTRL: */
863  const int CTRL_disp = (iword >> 2) & 0x3fffff;
864  uint32_t disp = CTRL_disp << 2;
865  if (disp & 0x00800000)
866  disp |= 0xff000000;
867 
868  ic->arg[0].u32 = disp + m_pc;
869 
870  if (opcode == 0x08) {
871  ic->f = instr_b;
872  }
873  } else if (opcode >= 0x58 && opcode <= 0x7f) {
874  /* REG: */
875  const int REG_src_dst = (iword >> 19) & 0x1f;
876  const int REG_src2 = (iword >> 14) & 0x1f;
877  const int REG_m3 = (iword >> 13) & 0x1;
878  const int REG_m2 = (iword >> 12) & 0x1;
879  const int REG_m1 = (iword >> 11) & 0x1;
880  const int REG_opcode2 = (iword >> 7) & 0xf;
881  const int REG_s2 = (iword >> 6) & 0x1;
882  const int REG_s1 = (iword >> 5) & 0x1;
883  const int REG_src1 = (iword >> 0) & 0x1f;
884 
885  int op3 = (opcode << 4) + REG_opcode2;
886 
887  if (REG_m1)
888  ic->arg[0].u32 = REG_src1;
889  else {
890  if (REG_s1)
891  ic->arg[0].p = &m_sfr[REG_src1];
892  else
893  ic->arg[0].p = &m_r[REG_src1];
894  }
895 
896  if (REG_m2)
897  ic->arg[1].u32 = REG_src2;
898  else {
899  if (REG_s2)
900  ic->arg[1].p = &m_sfr[REG_src1];
901  else
902  ic->arg[1].p = &m_r[REG_src2];
903  }
904 
905  if (REG_m3) {
906  // TODO: write to sfr.
907  if (ui != NULL)
908  ui->ShowDebugMessage(this, "unimplemented write to sfr");
909  return;
910  } else {
911  ic->arg[2].p = &m_r[REG_src_dst];
912  }
913 
914  void (*f_lit_lit_reg)(CPUDyntransComponent*, struct DyntransIC*) = NULL;
915  void (*f_lit_reg_reg)(CPUDyntransComponent*, struct DyntransIC*) = NULL;
916  void (*f_reg_lit_reg)(CPUDyntransComponent*, struct DyntransIC*) = NULL;
917  void (*f_reg_reg_reg)(CPUDyntransComponent*, struct DyntransIC*) = NULL;
918 
919  if (op3 == 0x5cc) {
920  // mov NOTE: mov does not use src2.
921  f_lit_lit_reg = instr_mov_lit_reg;
922  f_lit_reg_reg = instr_mov_lit_reg;
923  f_reg_lit_reg = instr_mov_reg_reg;
924  } else if (op3 == 0x659) {
925  // sysctl
926  f_reg_reg_reg = instr_sysctl;
927  }
928 
929  if (REG_m3 == 0) {
930  if (REG_m1 && REG_m2)
931  ic->f = f_lit_lit_reg;
932  if (REG_m1 && !REG_m2)
933  ic->f = f_lit_reg_reg;
934  if (!REG_m1 && REG_m2)
935  ic->f = f_reg_lit_reg;
936  if (!REG_m1 && !REG_m2)
937  ic->f = f_reg_reg_reg;
938  } else {
939  if (ui != NULL)
940  ui->ShowDebugMessage(this, "unimplemented write to sfr");
941  }
942  } else if (opcode >= 0x80 && opcode <= 0xcf) {
943  /* MEM: */
944 // const int MEMA_abase = (iword >> 14) & 0x1f;
945  const int MEMA_md = (iword >> 13) & 0x1;
946  const int MEMA_offset = (iword >> 0) & 0xfff;
947  const int MEMB_src_dst = (iword >> 19) & 0x1f;
948 // const int MEMB_abase = (iword >> 14) & 0x1f;
949  const int MEMB_mode = (iword >> 10) & 0xf;
950 // const int MEMB_scale = (iword >> 7) & 0x7;
951 // const int MEMB_index = (iword >> 0) & 0x1f;
952 
953  ic->arg[2].p = &m_r[MEMB_src_dst];
954 
955  if (iword & 0x1000) {
956  /* MEMB: */
957  switch (MEMB_mode) {
958  case 0xc:
959  ic->arg[0].u32 = iword2;
960  ic->f = instr_lda_displacement;
961  break;
962  default:
963  ui->ShowDebugMessage(this, "unimplemented MEMB_mode");
964  }
965  } else {
966  /* MEMA: */
967  if (MEMA_md)
968  ui->ShowDebugMessage(this, "TODO: MEMA");
969  else {
970  ic->arg[0].u32 = MEMA_offset;
971  ic->f = instr_mov_lit_reg;
972  }
973  }
974  }
975 
976  if (ic->f == NULL && ui != NULL) {
977  stringstream ss;
978  ss.flags(std::ios::hex);
979  ss << "unimplemented opcode 0x" << opcode;
980  if (opcode >= 0x58 && opcode <= 0x7f)
981  ss << ",0x" << ((iword >> 7) & 0xf);
982  ui->ShowDebugMessage(this, ss.str());
983  }
984 }
985 
986 
988 {
990 
991  cpu->DyntransToBeTranslatedBegin(ic);
992 
993  uint32_t iword;
994  if (cpu->DyntransReadInstruction(iword)) {
995  bool readCompleteInstruction = true;
996  uint32_t iword2 = 0;
997  uint32_t opcode = iword >> 24;
998  if (opcode >= 0x80 && opcode <= 0xcf) {
999  /* Only some MEMB instructions have displacement words: */
1000  int mode = (iword >> 10) & 0xf;
1001  if (mode == 0x5 || mode >= 0xc)
1002  readCompleteInstruction = cpu->DyntransReadInstruction(iword2, 4);
1003  if (!readCompleteInstruction) {
1004  UI* ui = cpu->GetUI();
1005  ui->ShowDebugMessage(cpu, "last part of instruction could not be read: TODO");
1006  }
1007  }
1008 
1009  if (readCompleteInstruction)
1010  cpu->Translate(iword, iword2, ic);
1011  }
1012 
1013  cpu->DyntransToBeTranslatedDone(ic);
1014 }
1015 
1016 
1017 /*****************************************************************************/
1018 
1019 
1020 #ifdef WITHUNITTESTS
1021 
1022 #include "ComponentFactory.h"
1023 
1024 static void Test_I960_CPUComponent_Create()
1025 {
1027  UnitTest::Assert("component was not created?", !cpu.IsNULL());
1028 
1029  const StateVariable * p = cpu->GetVariable("pfp");
1030  UnitTest::Assert("cpu has no pfp state variable?", p != NULL);
1031 }
1032 
1033 static GXemul SimpleMachine()
1034 {
1035  GXemul gxemul;
1036  gxemul.GetCommandInterpreter().RunCommand("add mainbus");
1037  gxemul.GetCommandInterpreter().RunCommand("add i960_cpu mainbus0");
1038  gxemul.GetCommandInterpreter().RunCommand("add ram mainbus0");
1039  gxemul.GetCommandInterpreter().RunCommand("ram0.memoryMappedBase = 0x3fe00000");
1040  gxemul.GetCommandInterpreter().RunCommand("ram0.memoryMappedSize = 0x1000");
1041  return gxemul;
1042 }
1043 
1044 static void Test_I960_CPUComponent_Disassembly_Basic()
1045 {
1046  GXemul gxemul = SimpleMachine();
1047  refcount_ptr<Component> i960_cpu = gxemul.GetRootComponent()->LookupPath("root.mainbus0.cpu0");
1048  CPUComponent* cpu = i960_cpu->AsCPUComponent();
1049  AddressDataBus* bus = cpu->AsAddressDataBus();
1050 
1051  vector<string> result;
1052  size_t len;
1053 
1054  // This assumes that the default endianness is little endian...
1055  bus->AddressSelect(0x3fe00048);
1056  bus->WriteData((uint32_t)0x8c683000, LittleEndian);
1057  bus->AddressSelect(0x3fe0004c);
1058  bus->WriteData((uint32_t)0x45342301, LittleEndian);
1059 
1060  len = cpu->DisassembleInstruction(0x3fe00048, result);
1061 
1062  UnitTest::Assert("disassembled instruction was wrong length?", len, 8);
1063  UnitTest::Assert("disassembly result incomplete?", result.size(), 3);
1064  UnitTest::Assert("disassembly result[0]", result[0], "8c683000 45342301");
1065  UnitTest::Assert("disassembly result[1]", result[1], "lda");
1066  UnitTest::Assert("disassembly result[2]", result[2], "0x45342301,r13");
1067 }
1068 
1069 static void Test_I960_CPUComponent_Execute_mov()
1070 {
1071  GXemul gxemul = SimpleMachine();
1072  refcount_ptr<Component> cpu = gxemul.GetRootComponent()->LookupPath("root.mainbus0.cpu0");
1073  AddressDataBus* bus = cpu->AsAddressDataBus();
1074 
1075  bus->AddressSelect(0x3fe00048);
1076  bus->WriteData((uint32_t)0x5c201e06, LittleEndian); // mov 6,r4
1077  bus->AddressSelect(0x3fe0004c);
1078  bus->WriteData((uint32_t)0x5c201e06, LittleEndian); // mov 6,r4
1079 
1080  cpu->SetVariableValue("pc", "0x3fe00048");
1081  cpu->SetVariableValue("r4", "0x1234");
1082 
1083  gxemul.SetRunState(GXemul::Running);
1084  gxemul.Execute(1);
1085 
1086  UnitTest::Assert("pc should have increased", cpu->GetVariable("pc")->ToInteger(), 0x3fe0004c);
1087  UnitTest::Assert("r4 should have been modified", cpu->GetVariable("r4")->ToInteger(), 6);
1088 
1089  cpu->SetVariableValue("r4", "0x12345");
1090 
1092  gxemul.Execute(1);
1093 
1094  UnitTest::Assert("pc should have increased again", cpu->GetVariable("pc")->ToInteger(), 0x3fe00050);
1095  UnitTest::Assert("r4 should have been modified again", cpu->GetVariable("r4")->ToInteger(), 6);
1096 }
1097 
1098 static void Test_I960_CPUComponent_Execute_b()
1099 {
1100  GXemul gxemul = SimpleMachine();
1101  refcount_ptr<Component> cpu = gxemul.GetRootComponent()->LookupPath("root.mainbus0.cpu0");
1102  AddressDataBus* bus = cpu->AsAddressDataBus();
1103 
1104  bus->AddressSelect(0x3fe00004);
1105  bus->WriteData((uint32_t)0x080006c0, LittleEndian); // b 0x3fe006c4
1106 
1107  cpu->SetVariableValue("pc", "0x3fe00004");
1108 
1109  gxemul.SetRunState(GXemul::Running);
1110  gxemul.Execute(1);
1111 
1112  UnitTest::Assert("pc should have changed", cpu->GetVariable("pc")->ToInteger(), 0x3fe006c4);
1113 
1114  cpu->SetVariableValue("pc", "0x3fe00004");
1115 
1117  gxemul.Execute(1);
1118 
1119  UnitTest::Assert("pc should have changed again", cpu->GetVariable("pc")->ToInteger(), 0x3fe006c4);
1120 }
1121 
1122 static void Test_I960_CPUComponent_Execute_lda_with_offset()
1123 {
1124  GXemul gxemul = SimpleMachine();
1125  refcount_ptr<Component> cpu = gxemul.GetRootComponent()->LookupPath("root.mainbus0.cpu0");
1126  AddressDataBus* bus = cpu->AsAddressDataBus();
1127 
1128  bus->AddressSelect(0x3fe00010);
1129  bus->WriteData((uint32_t)0x8c180f13, LittleEndian); // lda r3, 0xf13
1130 
1131  cpu->SetVariableValue("pc", "0x3fe00010");
1132  gxemul.SetRunState(GXemul::Running);
1133  gxemul.Execute(1);
1134  UnitTest::Assert("lda length", cpu->GetVariable("pc")->ToInteger(), 0x3fe00014);
1135  UnitTest::Assert("lda", cpu->GetVariable("r3")->ToInteger(), 0xf13);
1136 }
1137 
1138 static void Test_I960_CPUComponent_Execute_lda_with_displacement()
1139 {
1140  GXemul gxemul = SimpleMachine();
1141  refcount_ptr<Component> cpu = gxemul.GetRootComponent()->LookupPath("root.mainbus0.cpu0");
1142  AddressDataBus* bus = cpu->AsAddressDataBus();
1143 
1144  bus->AddressSelect(0x3fe00010);
1145  bus->WriteData((uint32_t)0x8cf03000, LittleEndian); // lda
1146  bus->AddressSelect(0x3fe00014);
1147  bus->WriteData((uint32_t)0x3fe0507c, LittleEndian); // 0x3fe0507c, g14
1148 
1149  cpu->SetVariableValue("pc", "0x3fe00010");
1150  gxemul.SetRunState(GXemul::Running);
1151  gxemul.Execute(1);
1152  UnitTest::Assert("lda length", cpu->GetVariable("pc")->ToInteger(), 0x3fe00018);
1153  UnitTest::Assert("lda", cpu->GetVariable("g14")->ToInteger(), 0x3fe0507c);
1154 }
1155 
1157 {
1158  UNITTEST(Test_I960_CPUComponent_Create);
1159  UNITTEST(Test_I960_CPUComponent_Disassembly_Basic);
1160 
1161  UNITTEST(Test_I960_CPUComponent_Execute_mov);
1162  UNITTEST(Test_I960_CPUComponent_Execute_b);
1163  UNITTEST(Test_I960_CPUComponent_Execute_lda_with_offset);
1164  UNITTEST(Test_I960_CPUComponent_Execute_lda_with_displacement);
1165 }
1166 
1167 #endif
I960_CPUComponent::DisassembleInstruction
virtual size_t DisassembleInstruction(uint64_t vaddr, vector< string > &result)
Disassembles an instruction into readable strings.
Definition: I960_CPUComponent.cc:326
DYNTRANS_INSTR
DYNTRANS_INSTR(I960_CPUComponent, b)
Definition: I960_CPUComponent.cc:779
ComponentFactory::GetCreationArgOverrides
static bool GetCreationArgOverrides(ComponentCreationSettings &settings, const ComponentCreateArgs &createArgs)
Get override arguments for component creation.
Definition: ComponentFactory.cc:151
GXemul::Running
@ Running
Definition: GXemul.h:61
Component::AddVariable
bool AddVariable(const string &name, T *variablePointer)
Adds a state variable of type T to the Component.
Definition: Component.h:563
I960_CPUComponent::FunctionTraceReturnImpl
virtual bool FunctionTraceReturnImpl(int64_t &retval)
Definition: I960_CPUComponent.cc:291
I960_CPUComponent::Create
static refcount_ptr< Component > Create(const ComponentCreateArgs &args)
Creates a I960_CPUComponent.
Definition: I960_CPUComponent.cc:159
CPUComponent::GetSymbolRegistry
SymbolRegistry & GetSymbolRegistry()
Gets a reference to the CPU's symbol registry.
Definition: CPUComponent.h:63
reg_instruction::has_src1
bool has_src1
Definition: I960_CPUComponent.cc:41
DYNTRANS_SYNCH_PC
#define DYNTRANS_SYNCH_PC
Definition: CPUDyntransComponent.h:82
ComponentFactory.h
I960_CPUComponent::FunctionTraceArgumentCount
virtual int FunctionTraceArgumentCount()
Definition: I960_CPUComponent.cc:279
GXemul
The main emulator class.
Definition: GXemul.h:55
reg_instruction::opcode
int opcode
Definition: I960_CPUComponent.cc:39
I960_CPUComponent.h
GXemul::GetCommandInterpreter
CommandInterpreter & GetCommandInterpreter()
Gets a reference to the CommandInterpreter.
Definition: GXemul.cc:623
LittleEndian
@ LittleEndian
Definition: misc.h:159
StateVariable
StateVariables make up the persistent state of Component objects.
Definition: StateVariable.h:69
CPUComponent::PreRunCheckForComponent
virtual bool PreRunCheckForComponent(GXemul *gxemul)
Checks the state of this component, before starting execution.
Definition: CPUComponent.cc:428
N_I960_SFRS
#define N_I960_SFRS
Definition: I960_CPUComponent.h:38
CPUComponent::m_frequency
double m_frequency
Definition: CPUComponent.h:194
refcount_ptr< Component >
UNITTESTS
#define UNITTESTS(class)
Helper for unit test case execution.
Definition: UnitTest.h:184
addr
uint32_t addr
Definition: tmp_arm_multi.cc:52
N_I960_REGS
#define N_I960_REGS
Definition: I960_CPUComponent.h:37
reg_instruction::mnemonic
const char * mnemonic
Definition: I960_CPUComponent.cc:40
Component::GetUI
UI * GetUI()
Gets an UI reference for outputting debug messages during runtime.
Definition: Component.cc:583
CPUDyntransComponent
A base-class for processors Component implementations that use dynamic translation.
Definition: CPUDyntransComponent.h:91
I960_CPUComponent::GetDyntransICshift
virtual int GetDyntransICshift() const
Definition: I960_CPUComponent.cc:298
REG32
#define REG32(arg)
Definition: CPUDyntransComponent.h:79
GXemul::GetRootComponent
refcount_ptr< Component > GetRootComponent()
Gets a pointer to the root configuration component.
Definition: GXemul.cc:659
UNITTEST
#define UNITTEST(functionname)
Helper for unit test case execution.
Definition: UnitTest.h:217
UI
Base class for a User Interface.
Definition: UI.h:42
I960_CPUComponent::CheckVariableWrite
virtual bool CheckVariableWrite(StateVariable &var, const string &oldValue)
Checks whether a write to a variable is OK.
Definition: I960_CPUComponent.cc:235
I960_CPUComponent::PCtoInstructionAddress
virtual uint64_t PCtoInstructionAddress(uint64_t pc)
Convert PC value to instuction address.
Definition: I960_CPUComponent.cc:320
UnitTest::Assert
static void Assert(const string &strFailMessage, bool condition)
Asserts that a boolean condition is correct.
Definition: UnitTest.cc:40
AddressDataBus::WriteData
virtual bool WriteData(const uint8_t &data, Endianness endianness=BigEndian)=0
Writes 8-bit data to the currently selected address.
DyntransIC
Definition: CPUDyntransComponent.h:55
CPUComponent::m_pc
uint64_t m_pc
Definition: CPUComponent.h:202
GXemul::SetRunState
void SetRunState(RunState newState)
Sets the RunState.
Definition: GXemul.cc:733
reg_instruction
Definition: I960_CPUComponent.cc:38
UI::ShowDebugMessage
virtual void ShowDebugMessage(const string &msg)=0
Shows a debug message.
I960_CPUComponent
A Component representing an Intel i960 processor.
Definition: I960_CPUComponent.h:73
ic
struct arm_instr_call * ic
Definition: tmp_arm_multi.cc:50
GXemul::Execute
void Execute(const int longestTotalRun=100000)
Run the emulation for "a while".
Definition: GXemul.cc:886
I960_CPUComponent::VirtualToPhysical
virtual bool VirtualToPhysical(uint64_t vaddr, uint64_t &paddr, bool &writable)
Virtual to physical address translation (MMU).
Definition: I960_CPUComponent.cc:311
SymbolRegistry::LookupAddress
string LookupAddress(uint64_t vaddr, bool allowOffset) const
Looks up an address.
Definition: SymbolRegistry.cc:48
I960_CPUComponent::ShowRegisters
virtual void ShowRegisters(GXemul *gxemul, const vector< string > &arguments) const
Definition: I960_CPUComponent.cc:243
reg_instruction::has_src2
bool has_src2
Definition: I960_CPUComponent.cc:42
CPUComponent::m_pageSize
int m_pageSize
Definition: CPUComponent.h:199
reg_instruction::has_dst
bool has_dst
Definition: I960_CPUComponent.cc:43
Component::LookupPath
const refcount_ptr< Component > LookupPath(string path) const
Looks up a path from this Component, and returns a pointer to the found Component,...
Definition: Component.cc:778
ComponentFactory::CreateComponent
static refcount_ptr< Component > CreateComponent(const string &componentNameAndOptionalArgs, GXemul *gxemul=NULL)
Creates a component given a short component name.
Definition: ComponentFactory.cc:87
I960_CPUComponent::ResetState
virtual void ResetState()
Resets the state variables of this component.
Definition: I960_CPUComponent.cc:198
AddressDataBus::AddressSelect
virtual void AddressSelect(uint64_t address)=0
Place an address on the bus.
DYNTRANS_INSTR_HEAD
#define DYNTRANS_INSTR_HEAD(class)
Definition: CPUDyntransComponent.h:77
settings
Definition: settings.cc:57
CPUComponent::m_isBigEndian
bool m_isBigEndian
Definition: CPUComponent.h:210
I960_CPUComponent::PreRunCheckForComponent
virtual bool PreRunCheckForComponent(GXemul *gxemul)
Checks the state of this component, before starting execution.
Definition: I960_CPUComponent.cc:223
DyntransIC::p
void * p
Definition: CPUDyntransComponent.h:59
reg
#define reg(x)
Definition: tmp_alpha_tail.cc:53
CommandInterpreter::RunCommand
bool RunCommand(const string &command, bool *pSuccess=NULL)
Runs a command, given as a string.
Definition: CommandInterpreter.cc:958
I960_G0
#define I960_G0
Definition: I960_CPUComponent.h:62
ComponentCreationSettings
map< string, string > ComponentCreationSettings
Definition: Component.h:46
symbol
Definition: symbol.h:37
Component::CheckVariableWrite
virtual bool CheckVariableWrite(StateVariable &var, const string &oldValue)
Checks whether a write to a variable is OK.
Definition: Component.cc:969
GXemul::GetUI
UI * GetUI()
Gets a pointer to the GXemul instance' active UI.
Definition: GXemul.cc:653
reg_instruction::has_src3
bool has_src3
Definition: I960_CPUComponent.cc:44
GXemul::SingleStepping
@ SingleStepping
Definition: GXemul.h:60
CPUComponent::ReadData
virtual bool ReadData(uint8_t &data, Endianness endianness)
Reads 8-bit data from the currently selected address.
Definition: CPUComponent.cc:504
I960_CPUComponent::FunctionTraceArgument
virtual int64_t FunctionTraceArgument(int n)
Definition: I960_CPUComponent.cc:285
I960_CPUComponent::GetDyntransToBeTranslated
virtual void(*)(CPUDyntransComponent *, DyntransIC *) GetDyntransToBeTranslated()
Definition: I960_CPUComponent.h:118
cpu
Definition: cpu.h:326
Component::AsCPUComponent
virtual CPUComponent * AsCPUComponent()
Returns the component's CPUComponent interface.
Definition: Component.cc:360
AddressDataBus
An interface for implementing components that read/write data via an address bus.
Definition: AddressDataBus.h:45
I960_CPUComponent::I960_CPUComponent
I960_CPUComponent()
Constructs a I960_CPUComponent.
Definition: I960_CPUComponent.cc:131
Component::GetAttribute
static string GetAttribute(const string &attributeName)
Creates a Component.
Definition: Component.cc:66
CPUComponent::ResetState
virtual void ResetState()
Resets the state variables of this component.
Definition: CPUComponent.cc:82
reg_instructions
struct reg_instruction reg_instructions[]
Definition: I960_CPUComponent.cc:47
BigEndian
@ BigEndian
Definition: misc.h:158
ComponentCreateArgs
Definition: Component.h:49
CPUComponent::AddressSelect
virtual void AddressSelect(uint64_t address)
Place an address on the bus.
Definition: CPUComponent.cc:498
I960_CPUComponent::GetAttribute
static string GetAttribute(const string &attributeName)
Definition: I960_CPUComponent.cc:767
GXemul.h
CPUComponent
A base-class for processors Component implementations.
Definition: CPUComponent.h:47

Generated on Tue Aug 25 2020 19:25:06 for GXemul by doxygen 1.8.18