I960_CPUComponent.cc Source File

Back to the index.

I960_CPUComponent.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2018 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 
165  if (!ComponentFactory::GetCreationArgOverrides(settings, args))
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  // 0 for most (?) i960 implementations. 3 for i960CA. (TODO: CF etc)
211  m_nr_of_valid_sfrs = 0;
212  if (m_model == "i960CA")
213  m_nr_of_valid_sfrs = 3;
214 
216 }
217 
218 
220 {
221  if (m_pc & 0x3) {
222  gxemul->GetUI()->ShowDebugMessage(this, "the pc register"
223  " can not have bit 0 or 1 set!\n");
224  return false;
225  }
226 
228 }
229 
230 
231 bool I960_CPUComponent::CheckVariableWrite(StateVariable& var, const string& oldValue)
232 {
233  // UI* ui = GetUI();
234 
235  return CPUDyntransComponent::CheckVariableWrite(var, oldValue);
236 }
237 
238 
239 void I960_CPUComponent::ShowRegisters(GXemul* gxemul, const vector<string>& arguments) const
240 {
241  stringstream ss;
242 
243  ss.flags(std::ios::hex);
244  ss << " ip = 0x" << std::setfill('0') << std::setw(8) << (uint32_t)m_pc;
245 
246  string symbol = GetSymbolRegistry().LookupAddress(m_pc, true);
247  if (symbol != "")
248  ss << " <" << symbol << ">";
249  ss << "\n";
250 
251  for (size_t i = 0; i < N_I960_REGS; i++) {
252  ss << std::setfill(' ') << std::setw(4) << i960_regnames[i]
253  << " = 0x" << std::setfill('0') << std::setw(8) << m_r[i];
254  if ((i&3) == 3)
255  ss << "\n";
256  else
257  ss << " ";
258  }
259 
260  for (size_t i = 0; i < m_nr_of_valid_sfrs; i++) {
261  stringstream name;
262  name << "sfr" << i;
263  ss << std::setfill(' ') << std::setw(6) << name.str()
264  << " = 0x" << std::setfill('0') << std::setw(8) << m_sfr[i];
265  if ((i&3) == 3)
266  ss << "\n";
267  else
268  ss << " ";
269  }
270 
271  gxemul->GetUI()->ShowDebugMessage(ss.str());
272 }
273 
274 
276 {
277  return 8;
278 }
279 
280 
282 {
283  return m_r[I960_G0 + n];
284 }
285 
286 
288 {
289  retval = m_r[I960_G0];
290  return true;
291 }
292 
293 
295 {
296  // 4 bytes per instruction means 2 bits shift.
297  return 2;
298 }
299 
300 
302 {
303  return instr_ToBeTranslated;
304 }
305 
306 
307 bool I960_CPUComponent::VirtualToPhysical(uint64_t vaddr, uint64_t& paddr,
308  bool& writable)
309 {
310  paddr = vaddr;
311  writable = true;
312  return true;
313 }
314 
315 
317 {
318  return pc;
319 }
320 
321 
322 size_t I960_CPUComponent::DisassembleInstruction(uint64_t vaddr, size_t maxLen,
323  unsigned char *instruction, vector<string>& result)
324 {
325  size_t instrSize = sizeof(uint32_t);
326 
327  if (maxLen < instrSize) {
328  assert(false);
329  return 0;
330  }
331 
332  // Read the instruction word:
333  uint32_t instructionWord = ((uint32_t *) (void *) instruction)[0];
334  if (m_isBigEndian)
335  instructionWord = BE32_TO_HOST(instructionWord);
336  else
337  instructionWord = LE32_TO_HOST(instructionWord);
338 
339  const uint32_t iword = instructionWord;
340 
341  const int opcode = iword >> 24;
342 
343  const int REG_src_dst = (iword >> 19) & 0x1f;
344  const int REG_src2 = (iword >> 14) & 0x1f;
345  const int REG_m3 = (iword >> 13) & 0x1;
346  const int REG_m2 = (iword >> 12) & 0x1;
347  const int REG_m1 = (iword >> 11) & 0x1;
348  const int REG_opcode2 = (iword >> 7) & 0xf;
349  const int REG_sfr2 = (iword >> 6) & 0x1;
350  const int REG_sfr1 = (iword >> 5) & 0x1;
351  const int REG_src1 = (iword >> 0) & 0x1f;
352 
353  const int COBR_src_dst = (iword >> 19) & 0x1f;
354  const int COBR_src_2 = (iword >> 14) & 0x1f;
355  const int COBR_m1 = (iword >> 13) & 0x1;
356  const int COBR_disp = (iword >> 2) & 0x7ff;
357  const int COBR_t = (iword >> 1) & 0x1;
358  const int COBR_s2 = (iword >> 0) & 0x1;
359 
360  const int CTRL_disp = (iword >> 2) & 0x3fffff;
361  const int CTRL_t = (iword >> 1) & 0x1;
362 
363  // const int MEMA_src_dst = (iword >> 19) & 0x1f; Same as MEMB_src_dst
364  const int MEMA_abase = (iword >> 14) & 0x1f;
365  const int MEMA_md = (iword >> 13) & 0x1;
366  // const int MEMA_zero = (iword >> 12) & 0x1; 0 for MEMA, 1 for MEMB
367  const int MEMA_offset = (iword >> 0) & 0xfff;
368 
369  const int MEMB_src_dst = (iword >> 19) & 0x1f;
370  const int MEMB_abase = (iword >> 14) & 0x1f;
371  const int MEMB_mode = (iword >> 10) & 0xf;
372  const int MEMB_scale = (iword >> 7) & 0x7;
373  // const int MEMB_sfr = (iword >> 5) & 0x3; Should be 00?
374  const int MEMB_index = (iword >> 0) & 0x1f;
375 
376  bool hasDisplacementWord = false;
377 
378  if (opcode >= 0x80 && iword & 0x1000) {
379  /* Only some MEMB instructions have displacement words: */
380  int mode = (iword >> 10) & 0xf;
381  if (mode == 0x5 || mode >= 0xc)
382  hasDisplacementWord = true;
383  }
384 
385  uint32_t displacementWord = 0;
386  if (hasDisplacementWord) {
387  instrSize += sizeof(uint32_t);
388  if (maxLen < instrSize)
389  return 0;
390 
391  displacementWord = ((uint32_t *) (void *) instruction)[1];
392  if (m_isBigEndian)
393  displacementWord = BE32_TO_HOST(displacementWord);
394  else
395  displacementWord = LE32_TO_HOST(displacementWord);
396  }
397 
398  stringstream ssHex;
399  ssHex.flags(std::ios::hex);
400  ssHex << std::setfill('0') << std::setw(8) << (uint32_t) iword;
401  if (hasDisplacementWord)
402  ssHex << " " << std::setfill('0') << std::setw(8) << (uint32_t) displacementWord;
403  else
404  ssHex << " ";
405 
406  result.push_back(ssHex.str());
407 
408 
409  stringstream ssOpcode;
410  stringstream ssArgs;
411  stringstream ssComments;
412 
413  if (opcode >= 0x08 && opcode <= 0x1f) {
414  /* CTRL: */
415  const char* mnemonics[] = {
416  "b", /* 0x08 */
417  "call", /* 0x09 */
418  "ret", /* 0x0a */
419  "bal", /* 0x0b */
420  "unknown_ctrl_0x0c", /* 0x0c */
421  "unknown_ctrl_0x0d", /* 0x0d */
422  "unknown_ctrl_0x0e", /* 0x0e */
423  "unknown_ctrl_0x0f", /* 0x0f */
424  "bno", /* 0x10 */
425  "bg", /* 0x11 */
426  "be", /* 0x12 */
427  "bge", /* 0x13 */
428  "bl", /* 0x14 */
429  "bne", /* 0x15 */
430  "ble", /* 0x16 */
431  "bo", /* 0x17 */
432  "faultno", /* 0x18 */
433  "faultg", /* 0x19 */
434  "faulte", /* 0x1a */
435  "faultge", /* 0x1b */
436  "faultl", /* 0x1c */
437  "faultne", /* 0x1d */
438  "faultle", /* 0x1e */
439  "faulto" /* 0x1f */
440  };
441 
442  ssOpcode << mnemonics[opcode - 0x08];
443  if (CTRL_t)
444  ssOpcode << ".f";
445 
446  bool hasDisplacement = opcode < 0x18 && opcode != 0x0a;
447  if (hasDisplacement) {
448  uint32_t disp = CTRL_disp << 2;
449  if (disp & 0x00800000)
450  disp |= 0xff000000;
451 
452  uint32_t addr = vaddr + disp;
453  ssArgs << "0x";
454  ssArgs.flags(std::ios::hex);
455  ssArgs << std::setfill('0') << std::setw(8) << addr;
456  }
457  } else if (opcode >= 0x20 && opcode <= 0x3f) {
458  /* COBR: */
459  const char* mnemonics[] = {
460  "testno", /* 0x20 */
461  "testg", /* 0x21 */
462  "teste", /* 0x22 */
463  "testge", /* 0x23 */
464  "testl", /* 0x24 */
465  "testne", /* 0x25 */
466  "testle", /* 0x26 */
467  "testo", /* 0x27 */
468 
469  "unknown_cobr_0x28", /* 0x28 */
470  "unknown_cobr_0x29", /* 0x29 */
471  "unknown_cobr_0x2a", /* 0x2a */
472  "unknown_cobr_0x2b", /* 0x2b */
473  "unknown_cobr_0x2c", /* 0x2c */
474  "unknown_cobr_0x2d", /* 0x2d */
475  "unknown_cobr_0x2e", /* 0x2e */
476  "unknown_cobr_0x2f", /* 0x2f */
477 
478  "bbc", /* 0x30 */
479  "cmpobg", /* 0x31 */
480  "cmpobe", /* 0x32 */
481  "cmpobge", /* 0x33 */
482  "cmpobl", /* 0x34 */
483  "cmpobne", /* 0x35 */
484  "cmpobne", /* 0x36 */
485  "bbs", /* 0x37 */
486 
487  "cmpibno", /* 0x38 */
488  "cmpibg", /* 0x39 */
489  "cmpibe", /* 0x3a */
490  "cmpibge", /* 0x3b */
491  "cmpibl", /* 0x3c */
492  "cmpibne", /* 0x3d */
493  "cmpible", /* 0x3e */
494  "cmpibo", /* 0x3f */
495  };
496 
497  ssOpcode << mnemonics[opcode - 0x20];
498  if (COBR_t)
499  ssOpcode << ".f";
500 
501  bool src1isBitpos = opcode == 0x30 || opcode == 0x37;
502 
503  if (opcode <= 0x27) {
504  ssArgs << regname_or_literal(COBR_src_dst, 0, COBR_s2);
505  } else {
506  uint32_t targ = COBR_disp << 2;
507  if (targ & 0x00001000)
508  targ |= 0xffffe000;
509  targ += vaddr;
510 
511  ssArgs << regname_or_literal(COBR_src_dst, src1isBitpos ? 1 : COBR_m1, 0) << ",";
512  ssArgs << regname_or_literal(COBR_src_2, 0, COBR_s2) << ",";
513  ssArgs << "0x";
514  ssArgs.flags(std::ios::hex);
515  ssArgs << std::setfill('0') << std::setw(8) << targ;
516  }
517  } else if (opcode >= 0x58 && opcode <= 0x7f) {
518  /* REG: */
519  struct reg_instruction *rinstr = NULL;
520  for (int i = 0; ; ++i) {
521  if (reg_instructions[i].mnemonic == NULL)
522  break;
523  if (reg_instructions[i].opcode == (opcode << 4) + REG_opcode2) {
524  rinstr = &reg_instructions[i];
525  break;
526  }
527  }
528 
529  bool has_src1 = true, has_src2 = true, has_dst = true, has_src3 = false;
530 
531  if (rinstr == NULL) {
532  ssOpcode << "unknown_reg_";
533  ssOpcode.flags(std::ios::hex);
534  ssOpcode << std::setfill('0') << std::setw(2) << opcode;
535  ssOpcode << ":" << std::setw(1) << REG_opcode2;
536  } else {
537  ssOpcode << rinstr->mnemonic;
538  has_src1 = rinstr->has_src1;
539  has_src2 = rinstr->has_src2;
540  has_dst = rinstr->has_dst;
541  has_src3 = rinstr->has_src3;
542  }
543 
544  if (has_src1)
545  ssArgs << regname_or_literal(REG_src1, REG_m1, REG_sfr1);
546 
547  if (has_src2) {
548  if (ssArgs.str().length() > 0)
549  ssArgs << ",";
550  ssArgs << regname_or_literal(REG_src2, REG_m2, REG_sfr2);
551  }
552 
553  if (has_dst) {
554  if (ssArgs.str().length() > 0)
555  ssArgs << ",";
556  if (REG_m3) {
557  /*
558  * The manual for i960CA says (when M3 = 1):
559  *
560  * "src/dst is a literal when used as a source
561  * or a special function register when used
562  * as a destination. M3 may not be 1 when
563  * src/dst is used both as a source and
564  * destination in an instruction (atmod,
565  * modify, extract, modpc)."
566  */
567  if (has_src3)
568  ssArgs << regname_or_literal(REG_src_dst, 1, 0);
569  else
570  ssArgs << regname_or_literal(REG_src_dst, 0, 1);
571  } else
572  ssArgs << regname_or_literal(REG_src_dst, 0, 0);
573  }
574  } else if (opcode >= 0x80 && opcode <= 0xcf) {
575  /* MEM: */
576 
577  /* NOTE: These are for i960CA. When implementing support for
578  other CPU variants, include an enum indicating which CPU
579  it is for so that a warning can be printed for instructions
580  that will cause faults on another CPU. */
581  const char* mnemonics[] = {
582  "ldob", /* 0x80 */
583  "unknown_mem_0x81", /* 0x81 BiiN ldvob */
584  "stob", /* 0x82 */
585  "unknown_mem_0x83", /* 0x83 BiiN stvob */
586  "bx", /* 0x84 */
587  "balx", /* 0x85 */
588  "callx", /* 0x86 */
589  "unknown_mem_0x87", /* 0x87 */
590 
591  "ldos", /* 0x88 */
592  "unknown_mem_0x89", /* 0x89 BiiN ldvos */
593  "stos", /* 0x8a */
594  "unknown_mem_0x8b", /* 0x8b BiiN stvos */
595  "lda", /* 0x8c */
596  "unknown_mem_0x8d", /* 0x8d */
597  "unknown_mem_0x8e", /* 0x8e */
598  "unknown_mem_0x8f", /* 0x8f */
599 
600  "ld", /* 0x90 */
601  "unknown_mem_0x91", /* 0x91 BiiN ldv */
602  "st", /* 0x92 */
603  "unknown_mem_0x93", /* 0x93 Biin stv */
604  "unknown_mem_0x94", /* 0x94 */
605  "unknown_mem_0x95", /* 0x95 */
606  "unknown_mem_0x96", /* 0x96 */
607  "unknown_mem_0x97", /* 0x97 */
608 
609  "ldl", /* 0x98 */
610  "unknown_mem_0x99", /* 0x99 BiiN ldvl */
611  "stl", /* 0x9a */
612  "unknown_mem_0x9b", /* 0x9b BiiN stvl */
613  "unknown_mem_0x9c", /* 0x9c */
614  "unknown_mem_0x9d", /* 0x9d */
615  "unknown_mem_0x9e", /* 0x9e */
616  "unknown_mem_0x9f", /* 0x9f */
617 
618  "ldt", /* 0xa0 */
619  "unknown_mem_0xa1", /* 0xa1 BiiN ldvt */
620  "stt", /* 0xa2 */
621  "unknown_mem_0xa3", /* 0xa3 Biin stvt */
622  "unknown_mem_0xa4", /* 0xa4 */
623  "unknown_mem_0xa5", /* 0xa5 */
624  "unknown_mem_0xa6", /* 0xa6 */
625  "unknown_mem_0xa7", /* 0xa7 */
626 
627  "unknown_mem_0xa8", /* 0xa8 */
628  "unknown_mem_0xa9", /* 0xa9 */
629  "unknown_mem_0xaa", /* 0xaa */
630  "unknown_mem_0xab", /* 0xab */
631  "unknown_mem_0xac", /* 0xac */
632  "unknown_mem_0xad", /* 0xad */
633  "unknown_mem_0xae", /* 0xae */
634  "unknown_mem_0xaf", /* 0xaf */
635 
636  "ldq", /* 0xb0 */
637  "unknown_mem_0xb1", /* 0xb1 BiiN ldvq */
638  "stq", /* 0xb2 */
639  "unknown_mem_0xb3", /* 0xb3 BiiN stvq */
640  "unknown_mem_0xb4", /* 0xb4 */
641  "unknown_mem_0xb5", /* 0xb5 */
642  "unknown_mem_0xb6", /* 0xb6 */
643  "unknown_mem_0xb7", /* 0xb7 */
644 
645  "unknown_mem_0xb8", /* 0xb8 */
646  "unknown_mem_0xb9", /* 0xb9 */
647  "unknown_mem_0xba", /* 0xba */
648  "unknown_mem_0xbb", /* 0xbb */
649  "unknown_mem_0xbc", /* 0xbc */
650  "unknown_mem_0xbd", /* 0xbd */
651  "unknown_mem_0xbe", /* 0xbe */
652  "unknown_mem_0xbf", /* 0xbf */
653 
654  "ldib", /* 0xc0 */
655  "unknown_mem_0xc1", /* 0xc1 BiiN ldvib */
656  "stib", /* 0xc2 */
657  "unknown_mem_0xc3", /* 0xc3 Biin stvib */
658  "unknown_mem_0xc4", /* 0xc4 */
659  "unknown_mem_0xc5", /* 0xc5 */
660  "unknown_mem_0xc6", /* 0xc6 */
661  "unknown_mem_0xc7", /* 0xc7 */
662 
663  "ldis", /* 0xc8 */
664  "unknown_mem_0xc9", /* 0xc9 BiiN ldvis */
665  "stis", /* 0xca */
666  "unknown_mem_0xcb", /* 0xcb BiiN stvis */
667  "unknown_mem_0xcc", /* 0xcc */
668  "unknown_mem_0xcd", /* 0xcd */
669  "unknown_mem_0xce", /* 0xce */
670  "unknown_mem_0xcf", /* 0xcf */
671 
672  /* BiiN:
673  d0 = ldm
674  d1 = ldvm
675  d2 = stm
676  d3 = stvm
677  d8 = ldml
678  d9 = ldvml
679  da = stml
680  db = stvml */
681  };
682 
683  ssOpcode << mnemonics[opcode - 0x80];
684 
685  bool usesDst = opcode != 0x84 && opcode != 0x86;
686  bool isStore = !!(opcode & 2);
687 
688  if (usesDst && isStore) {
689  ssArgs << regname_or_literal(MEMB_src_dst, 0, 0) << ",";
690  }
691 
692  if (iword & 0x1000) {
693  /* MEMB: */
694  int scale = 1 << MEMB_scale;
695  switch (MEMB_mode) {
696  case 0x4:
697  ssArgs << "(" << regname_or_literal(MEMB_abase, 0, 0) << ")";
698  break;
699  case 0x5:
700  {
701  uint32_t offset = displacementWord + 8;
702  ssArgs << "0x";
703  ssArgs.flags(std::ios::hex);
704  ssArgs << std::setfill('0') << std::setw(8) << offset;
705  ssArgs << "(ip)";
706  }
707  break;
708  case 0x7:
709  // (reg1)[reg2 * scale]
710  ssArgs << "(" << regname_or_literal(MEMB_abase, 0, 0) << ")";
711  ssArgs << "[" << regname_or_literal(MEMB_index, 0, 0) << "*" << scale << "]";
712  break;
713  case 0xc:
714  case 0xd:
715  {
716  uint32_t offset = displacementWord;
717  ssArgs << "0x";
718  ssArgs.flags(std::ios::hex);
719  ssArgs << std::setfill('0') << std::setw(8) << offset;
720  if (MEMB_mode == 0xd)
721  ssArgs << "(" << regname_or_literal(MEMB_abase, 0, 0) << ")";
722  }
723  break;
724  case 0xe:
725  case 0xf:
726  {
727  uint32_t offset = displacementWord;
728  ssArgs << "0x";
729  ssArgs.flags(std::ios::hex);
730  ssArgs << std::setfill('0') << std::setw(8) << offset;
731  if (MEMB_mode == 0xf)
732  ssArgs << "(" << regname_or_literal(MEMB_abase, 0, 0) << ")";
733  ssArgs << "[" << regname_or_literal(MEMB_index, 0, 0) << "*" << scale << "]";
734  }
735  break;
736  default:
737  ssArgs << "unimplemented MEMB mode!";
738  }
739  } else {
740  /* MEMA: */
741  ssArgs << "0x";
742  ssArgs.flags(std::ios::hex);
743  ssArgs << std::setfill('0') << std::setw(1) << MEMA_offset;
744 
745  if (MEMA_md)
746  ssArgs << "(" << regname_or_literal(MEMA_abase, 0, 0) << ")";
747  }
748 
749  if (usesDst && !isStore) {
750  ssArgs << "," << regname_or_literal(MEMB_src_dst, 0, 0);
751  }
752  } else if (iword == 0) {
753  ssOpcode << "--";
754  } else {
755  ssOpcode << "unknown_0x";
756  ssOpcode.flags(std::ios::hex);
757  ssOpcode << std::setfill('0') << std::setw(2) << (int)opcode;
758  }
759 
760  result.push_back(ssOpcode.str());
761  result.push_back(ssArgs.str());
762  string comments = ssComments.str();
763  if (comments.length() > 0)
764  result.push_back(comments);
765 
766  return instrSize;
767 }
768 
769 
770 string I960_CPUComponent::GetAttribute(const string& attributeName)
771 {
772  if (attributeName == "stable")
773  return "yes";
774 
775  if (attributeName == "description")
776  return "Intel i960 processor.";
777 
778  return Component::GetAttribute(attributeName);
779 }
780 
781 
782 /*****************************************************************************/
783 
784 
786 {
788  cpu->m_pc = ic->arg[0].u32;
789  cpu->DyntransPCtoPointers();
790 }
791 
792 
794 {
796  REG32(ic->arg[2]) = ic->arg[0].u32;
797  cpu->m_nextIC = ic + 2;
798 }
799 
800 
802 {
803  REG32(ic->arg[2]) = ic->arg[0].u32;
804 }
805 
806 
808 {
810 
811  uint32_t message = REG32(ic->arg[0]);
812  int type = (message >> 8) & 0xff;
813 
814  if (type == 0x01) {
815  // Invalidate cache.
816  // Right now in GXemul, this is a NOP.
817  UI* ui = cpu->GetUI();
818  ui->ShowDebugMessage(cpu, "invalidating cache (no-op for now)");
819  } else {
820 
821  // We didn't actually do anything in this instruction.
822  cpu->m_executedCycles --;
823 
824  // Point to this instruction...
826 
827  // ... and then abort.
828  cpu->m_nextIC = &cpu->m_abortIC;
829 
830  UI* ui = cpu->GetUI();
831  ui->ShowDebugMessage(cpu, "unimplemented sysctl message type");
832  }
833 }
834 
835 
836 /*****************************************************************************/
837 
838 
839 void I960_CPUComponent::Translate(uint32_t iword, uint32_t iword2, struct DyntransIC* ic)
840 {
841  UI* ui = GetUI(); // for debug messages
842 
843  unsigned int opcode = iword >> 24;
844 
845  if (opcode >= 0x08 && opcode <= 0x1f) {
846  /* CTRL: */
847  const int CTRL_disp = (iword >> 2) & 0x3fffff;
848  uint32_t disp = CTRL_disp << 2;
849  if (disp & 0x00800000)
850  disp |= 0xff000000;
851 
852  ic->arg[0].u32 = disp + m_pc;
853 
854  if (opcode == 0x08) {
855  ic->f = instr_b;
856  }
857  } else if (opcode >= 0x58 && opcode <= 0x7f) {
858  /* REG: */
859  const int REG_src_dst = (iword >> 19) & 0x1f;
860  const int REG_src2 = (iword >> 14) & 0x1f;
861  const int REG_m3 = (iword >> 13) & 0x1;
862  const int REG_m2 = (iword >> 12) & 0x1;
863  const int REG_m1 = (iword >> 11) & 0x1;
864  const int REG_opcode2 = (iword >> 7) & 0xf;
865  const int REG_s2 = (iword >> 6) & 0x1;
866  const int REG_s1 = (iword >> 5) & 0x1;
867  const int REG_src1 = (iword >> 0) & 0x1f;
868 
869  int op3 = (opcode << 4) + REG_opcode2;
870 
871  if (REG_m1)
872  ic->arg[0].u32 = REG_src1;
873  else {
874  if (REG_s1)
875  ic->arg[0].p = &m_sfr[REG_src1];
876  else
877  ic->arg[0].p = &m_r[REG_src1];
878  }
879 
880  if (REG_m2)
881  ic->arg[1].u32 = REG_src2;
882  else {
883  if (REG_s2)
884  ic->arg[1].p = &m_sfr[REG_src1];
885  else
886  ic->arg[1].p = &m_r[REG_src2];
887  }
888 
889  if (REG_m3) {
890  // TODO: write to sfr.
891  if (ui != NULL)
892  ui->ShowDebugMessage(this, "unimplemented write to sfr");
893  return;
894  } else {
895  ic->arg[2].p = &m_r[REG_src_dst];
896  }
897 
898  void (*f_lit_lit_reg)(CPUDyntransComponent*, struct DyntransIC*) = NULL;
899  void (*f_lit_reg_reg)(CPUDyntransComponent*, struct DyntransIC*) = NULL;
900  void (*f_reg_lit_reg)(CPUDyntransComponent*, struct DyntransIC*) = NULL;
901  void (*f_reg_reg_reg)(CPUDyntransComponent*, struct DyntransIC*) = NULL;
902 
903  if (op3 == 0x5cc) {
904  // mov NOTE: mov does not use src2.
905  f_lit_lit_reg = instr_mov_lit_reg;
906  f_lit_reg_reg = instr_mov_lit_reg;
907  } else if (op3 == 0x659) {
908  // sysctl
909  f_reg_reg_reg = instr_sysctl;
910  }
911 
912  if (REG_m3 == 0) {
913  if (REG_m1 && REG_m2)
914  ic->f = f_lit_lit_reg;
915  if (REG_m1 && !REG_m2)
916  ic->f = f_lit_reg_reg;
917  if (!REG_m1 && REG_m2)
918  ic->f = f_reg_lit_reg;
919  if (!REG_m1 && !REG_m2)
920  ic->f = f_reg_reg_reg;
921  } else {
922  if (ui != NULL)
923  ui->ShowDebugMessage(this, "unimplemented write to sfr");
924  }
925  } else if (opcode >= 0x80 && opcode <= 0xcf) {
926  /* MEM: */
927 // const int MEMA_abase = (iword >> 14) & 0x1f;
928  const int MEMA_md = (iword >> 13) & 0x1;
929  const int MEMA_offset = (iword >> 0) & 0xfff;
930  const int MEMB_src_dst = (iword >> 19) & 0x1f;
931 // const int MEMB_abase = (iword >> 14) & 0x1f;
932  const int MEMB_mode = (iword >> 10) & 0xf;
933 // const int MEMB_scale = (iword >> 7) & 0x7;
934 // const int MEMB_index = (iword >> 0) & 0x1f;
935 
936  ic->arg[2].p = &m_r[MEMB_src_dst];
937 
938  if (iword & 0x1000) {
939  /* MEMB: */
940  switch (MEMB_mode) {
941  case 0xc:
942  ic->arg[0].u32 = iword2;
943  ic->f = instr_lda_displacement;
944  break;
945  default:
946  ui->ShowDebugMessage(this, "unimplemented MEMB_mode");
947  }
948  } else {
949  /* MEMA: */
950  if (MEMA_md)
951  ui->ShowDebugMessage(this, "TODO: MEMA");
952  else {
953  ic->arg[0].u32 = MEMA_offset;
954  ic->f = instr_mov_lit_reg;
955  }
956  }
957  }
958 
959  if (ic->f == NULL && ui != NULL) {
960  stringstream ss;
961  ss.flags(std::ios::hex);
962  ss << "unimplemented opcode 0x" << opcode;
963  ui->ShowDebugMessage(this, ss.str());
964  }
965 }
966 
967 
969 {
971 
972  cpu->DyntransToBeTranslatedBegin(ic);
973 
974  uint32_t iword;
975  if (cpu->DyntransReadInstruction(iword)) {
976  bool readCompleteInstruction = true;
977  uint32_t iword2 = 0;
978  uint32_t opcode = iword >> 24;
979  if (opcode >= 0x80 && opcode <= 0xcf) {
980  /* Only some MEMB instructions have displacement words: */
981  int mode = (iword >> 10) & 0xf;
982  if (mode == 0x5 || mode >= 0xc)
983  readCompleteInstruction = cpu->DyntransReadInstruction(iword2, 4);
984  if (!readCompleteInstruction) {
985  UI* ui = cpu->GetUI();
986  ui->ShowDebugMessage(cpu, "last part of instruction could not be read: TODO");
987  }
988  }
989 
990  if (readCompleteInstruction)
991  cpu->Translate(iword, iword2, ic);
992  }
993 
994  cpu->DyntransToBeTranslatedDone(ic);
995 }
996 
997 
998 /*****************************************************************************/
999 
1000 
1001 #ifdef WITHUNITTESTS
1002 
1003 #include "ComponentFactory.h"
1004 
1005 static void Test_I960_CPUComponent_Create()
1006 {
1008  UnitTest::Assert("component was not created?", !cpu.IsNULL());
1009 
1010  const StateVariable * p = cpu->GetVariable("pfp");
1011  UnitTest::Assert("cpu has no pfp state variable?", p != NULL);
1012 }
1013 
1014 static void Test_I960_CPUComponent_Disassembly_Basic()
1015 {
1017  CPUComponent* cpu = i960_cpu->AsCPUComponent();
1018 
1019  vector<string> result;
1020  size_t len;
1021  unsigned char instruction[sizeof(uint32_t) * 2];
1022 
1023  // This assumes that the default endianness is little endian...
1024  instruction[0] = 0x00;
1025  instruction[1] = 0x30;
1026  instruction[2] = 0x68;
1027  instruction[3] = 0x8c;
1028 
1029  instruction[4] = 0x01;
1030  instruction[5] = 0x23;
1031  instruction[6] = 0x34;
1032  instruction[7] = 0x45;
1033 
1034  len = cpu->DisassembleInstruction(0x12345678, sizeof(instruction), instruction, result);
1035 
1036  UnitTest::Assert("disassembled instruction was wrong length?", len, 8);
1037  UnitTest::Assert("disassembly result incomplete?", result.size(), 3);
1038  UnitTest::Assert("disassembly result[0]", result[0], "8c683000 45342301");
1039  UnitTest::Assert("disassembly result[1]", result[1], "lda");
1040  UnitTest::Assert("disassembly result[2]", result[2], "0x45342301,r13");
1041 }
1042 
1043 static GXemul SimpleMachine()
1044 {
1045  GXemul gxemul;
1046  gxemul.GetCommandInterpreter().RunCommand("add mainbus");
1047  gxemul.GetCommandInterpreter().RunCommand("add i960_cpu mainbus0");
1048  gxemul.GetCommandInterpreter().RunCommand("add ram mainbus0");
1049  gxemul.GetCommandInterpreter().RunCommand("ram0.memoryMappedBase = 0x3fe00000");
1050  gxemul.GetCommandInterpreter().RunCommand("ram0.memoryMappedSize = 0x1000");
1051  return gxemul;
1052 }
1053 
1054 static void Test_I960_CPUComponent_Execute_mov()
1055 {
1056  GXemul gxemul = SimpleMachine();
1057  refcount_ptr<Component> cpu = gxemul.GetRootComponent()->LookupPath("root.mainbus0.cpu0");
1058  AddressDataBus* bus = cpu->AsAddressDataBus();
1059 
1060  bus->AddressSelect(0x3fe00048);
1061  bus->WriteData((uint32_t)0x5c201e06, LittleEndian); // mov 6,r4
1062  bus->AddressSelect(0x3fe0004c);
1063  bus->WriteData((uint32_t)0x5c201e06, LittleEndian); // mov 6,r4
1064 
1065  cpu->SetVariableValue("pc", "0x3fe00048");
1066  cpu->SetVariableValue("r4", "0x1234");
1067 
1068  gxemul.SetRunState(GXemul::Running);
1069  gxemul.Execute(1);
1070 
1071  UnitTest::Assert("pc should have increased", cpu->GetVariable("pc")->ToInteger(), 0x3fe0004c);
1072  UnitTest::Assert("r4 should have been modified", cpu->GetVariable("r4")->ToInteger(), 6);
1073 
1074  cpu->SetVariableValue("r4", "0x12345");
1075 
1077  gxemul.Execute(1);
1078 
1079  UnitTest::Assert("pc should have increased again", cpu->GetVariable("pc")->ToInteger(), 0x3fe00050);
1080  UnitTest::Assert("r4 should have been modified again", cpu->GetVariable("r4")->ToInteger(), 6);
1081 }
1082 
1083 static void Test_I960_CPUComponent_Execute_b()
1084 {
1085  GXemul gxemul = SimpleMachine();
1086  refcount_ptr<Component> cpu = gxemul.GetRootComponent()->LookupPath("root.mainbus0.cpu0");
1087  AddressDataBus* bus = cpu->AsAddressDataBus();
1088 
1089  bus->AddressSelect(0x3fe00004);
1090  bus->WriteData((uint32_t)0x080006c0, LittleEndian); // b 0x3fe006c4
1091 
1092  cpu->SetVariableValue("pc", "0x3fe00004");
1093 
1094  gxemul.SetRunState(GXemul::Running);
1095  gxemul.Execute(1);
1096 
1097  UnitTest::Assert("pc should have changed", cpu->GetVariable("pc")->ToInteger(), 0x3fe006c4);
1098 
1099  cpu->SetVariableValue("pc", "0x3fe00004");
1100 
1102  gxemul.Execute(1);
1103 
1104  UnitTest::Assert("pc should have changed again", cpu->GetVariable("pc")->ToInteger(), 0x3fe006c4);
1105 }
1106 
1107 static void Test_I960_CPUComponent_Execute_lda_with_offset()
1108 {
1109  GXemul gxemul = SimpleMachine();
1110  refcount_ptr<Component> cpu = gxemul.GetRootComponent()->LookupPath("root.mainbus0.cpu0");
1111  AddressDataBus* bus = cpu->AsAddressDataBus();
1112 
1113  bus->AddressSelect(0x3fe00010);
1114  bus->WriteData((uint32_t)0x8c180f13, LittleEndian); // lda r3, 0xf13
1115 
1116  cpu->SetVariableValue("pc", "0x3fe00010");
1117  gxemul.SetRunState(GXemul::Running);
1118  gxemul.Execute(1);
1119  UnitTest::Assert("lda length", cpu->GetVariable("pc")->ToInteger(), 0x3fe00014);
1120  UnitTest::Assert("lda", cpu->GetVariable("r3")->ToInteger(), 0xf13);
1121 }
1122 
1123 static void Test_I960_CPUComponent_Execute_lda_with_displacement()
1124 {
1125  GXemul gxemul = SimpleMachine();
1126  refcount_ptr<Component> cpu = gxemul.GetRootComponent()->LookupPath("root.mainbus0.cpu0");
1127  AddressDataBus* bus = cpu->AsAddressDataBus();
1128 
1129  bus->AddressSelect(0x3fe00010);
1130  bus->WriteData((uint32_t)0x8cf03000, LittleEndian); // lda
1131  bus->AddressSelect(0x3fe00014);
1132  bus->WriteData((uint32_t)0x3fe0507c, LittleEndian); // 0x3fe0507c, g14
1133 
1134  cpu->SetVariableValue("pc", "0x3fe00010");
1135  gxemul.SetRunState(GXemul::Running);
1136  gxemul.Execute(1);
1137  UnitTest::Assert("lda length", cpu->GetVariable("pc")->ToInteger(), 0x3fe00018);
1138  UnitTest::Assert("lda", cpu->GetVariable("g14")->ToInteger(), 0x3fe0507c);
1139 }
1140 
1142 {
1143  UNITTEST(Test_I960_CPUComponent_Create);
1144  UNITTEST(Test_I960_CPUComponent_Disassembly_Basic);
1145 
1146  UNITTEST(Test_I960_CPUComponent_Execute_mov);
1147  UNITTEST(Test_I960_CPUComponent_Execute_b);
1148  UNITTEST(Test_I960_CPUComponent_Execute_lda_with_offset);
1149  UNITTEST(Test_I960_CPUComponent_Execute_lda_with_displacement);
1150 }
1151 
1152 #endif
void SetRunState(RunState newState)
Sets the RunState.
Definition: GXemul.cc:741
virtual CPUComponent * AsCPUComponent()
Returns the component&#39;s CPUComponent interface.
Definition: Component.cc:360
double m_frequency
Definition: CPUComponent.h:197
#define I960_G0
virtual void ShowDebugMessage(const string &msg)=0
Shows a debug message.
virtual int GetDyntransICshift() const
StateVariable * GetVariable(const string &name)
Gets a pointer to a state variable.
Definition: Component.cc:949
DYNTRANS_INSTR(I960_CPUComponent, b)
static refcount_ptr< Component > CreateComponent(const string &componentNameAndOptionalArgs, GXemul *gxemul=NULL)
Creates a component given a short component name.
void(* f)(CPUDyntransComponent *, DyntransIC *)
A Component representing an Intel i960 processor.
struct arm_instr_call * ic
#define BE32_TO_HOST(x)
Definition: misc.h:181
virtual int FunctionTraceArgumentCount()
virtual bool PreRunCheckForComponent(GXemul *gxemul)
Checks the state of this component, before starting execution.
bool RunCommand(const string &command, bool *pSuccess=NULL)
Runs a command, given as a string.
virtual void ResetState()
Resets the state variables of this component.
bool AddVariable(const string &name, T *variablePointer)
Adds a state variable of type T to the Component.
Definition: Component.h:563
UI * GetUI()
Gets an UI reference for outputting debug messages during runtime.
Definition: Component.cc:583
virtual bool WriteData(const uint8_t &data, Endianness endianness=BigEndian)=0
Writes 8-bit data to the currently selected address.
#define REG32(arg)
union DyntransIC::@0 arg[N_DYNTRANS_IC_ARGS]
#define reg(x)
A dyntrans instruction call.
I960_CPUComponent()
Constructs a I960_CPUComponent.
virtual uint64_t PCtoInstructionAddress(uint64_t pc)
Convert PC value to instuction address.
virtual int64_t FunctionTraceArgument(int n)
An interface for implementing components that read/write data via an address bus. ...
static string GetAttribute(const string &attributeName)
Creates a Component.
Definition: Component.cc:66
The main emulator class.
Definition: GXemul.h:54
#define UNITTESTS(class)
Helper for unit test case execution.
Definition: UnitTest.h:184
CommandInterpreter & GetCommandInterpreter()
Gets a reference to the CommandInterpreter.
Definition: GXemul.cc:631
map< string, string > ComponentCreationSettings
Definition: Component.h:46
static refcount_ptr< Component > Create(const ComponentCreateArgs &args)
Creates a I960_CPUComponent.
#define LE32_TO_HOST(x)
Definition: misc.h:180
static string GetAttribute(const string &attributeName)
string LookupAddress(uint64_t vaddr, bool allowOffset) const
Looks up an address.
const char * mnemonic
virtual bool PreRunCheckForComponent(GXemul *gxemul)
Checks the state of this component, before starting execution.
bool m_isBigEndian
Definition: CPUComponent.h:213
#define DYNTRANS_SYNCH_PC
uint64_t m_pc
Definition: CPUComponent.h:205
SymbolRegistry & GetSymbolRegistry()
Gets a reference to the CPU&#39;s symbol registry.
Definition: CPUComponent.h:63
uint32_t addr
virtual bool VirtualToPhysical(uint64_t vaddr, uint64_t &paddr, bool &writable)
Virtual to physical address translation (MMU).
virtual bool CheckVariableWrite(StateVariable &var, const string &oldValue)
Checks whether a write to a variable is OK.
Definition: cpu.h:326
#define N_I960_REGS
A base-class for processors Component implementations that use dynamic translation.
uint64_t ToInteger() const
Returns the variable as an unsignedinteger value.
virtual size_t DisassembleInstruction(uint64_t vaddr, size_t maxlen, unsigned char *instruction, vector< string > &result)
Disassembles an instruction into readable strings.
StateVariables make up the persistent state of Component objects.
Definition: StateVariable.h:67
virtual bool CheckVariableWrite(StateVariable &var, const string &oldValue)
Checks whether a write to a variable is OK.
Definition: Component.cc:969
virtual void ShowRegisters(GXemul *gxemul, const vector< string > &arguments) const
A base-class for processors Component implementations.
Definition: CPUComponent.h:43
virtual size_t DisassembleInstruction(uint64_t vaddr, size_t maxLen, unsigned char *instruction, vector< string > &result)=0
Disassembles an instruction into readable strings.
static void Assert(const string &strFailMessage, bool condition)
Asserts that a boolean condition is correct.
Definition: UnitTest.cc:40
virtual void AddressSelect(uint64_t address)=0
Place an address on the bus.
virtual void ResetState()
Resets the state variables of this component.
Definition: CPUComponent.cc:82
bool SetVariableValue(const string &name, const string &expression)
Sets a variable to a new value.
Definition: Component.cc:1030
refcount_ptr< Component > GetRootComponent()
Gets a pointer to the root configuration component.
Definition: GXemul.cc:667
virtual AddressDataBus * AsAddressDataBus()
Returns the component&#39;s AddressDataBus interface, if any.
Definition: Component.cc:367
Definition: symbol.h:37
#define N_I960_SFRS
#define DYNTRANS_INSTR_HEAD(class)
UI * GetUI()
Gets a pointer to the GXemul instance&#39; active UI.
Definition: GXemul.cc:661
static bool GetCreationArgOverrides(ComponentCreationSettings &settings, const ComponentCreateArgs &createArgs)
Get override arguments for component creation.
Base class for a User Interface.
Definition: UI.h:40
const refcount_ptr< Component > LookupPath(string path) const
Looks up a path from this Component, and returns a pointer to the found Component, if any.
Definition: Component.cc:778
void Execute(const int longestTotalRun=100000)
Run the emulation for "a while".
Definition: GXemul.cc:894
virtual void(*)(CPUDyntransComponent *, DyntransIC *) GetDyntransToBeTranslated()
struct reg_instruction reg_instructions[]
#define UNITTEST(functionname)
Helper for unit test case execution.
Definition: UnitTest.h:217
bool IsNULL() const
Checks whether or not an object is referenced by the reference counted pointer.
Definition: refcount_ptr.h:216
virtual bool FunctionTraceReturnImpl(int64_t &retval)

Generated on Fri Dec 7 2018 19:52:23 for GXemul by doxygen 1.8.13