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  result.push_back(ssHex.str());
406 
407 
408  stringstream ssOpcode;
409  stringstream ssArgs;
410  stringstream ssComments;
411 
412  if (opcode >= 0x08 && opcode <= 0x1f) {
413  /* CTRL: */
414  const char* mnemonics[] = {
415  "b", /* 0x08 */
416  "call", /* 0x09 */
417  "ret", /* 0x0a */
418  "bal", /* 0x0b */
419  "unknown_ctrl_0x0c", /* 0x0c */
420  "unknown_ctrl_0x0d", /* 0x0d */
421  "unknown_ctrl_0x0e", /* 0x0e */
422  "unknown_ctrl_0x0f", /* 0x0f */
423  "bno", /* 0x10 */
424  "bg", /* 0x11 */
425  "be", /* 0x12 */
426  "bge", /* 0x13 */
427  "bl", /* 0x14 */
428  "bne", /* 0x15 */
429  "ble", /* 0x16 */
430  "bo", /* 0x17 */
431  "faultno", /* 0x18 */
432  "faultg", /* 0x19 */
433  "faulte", /* 0x1a */
434  "faultge", /* 0x1b */
435  "faultl", /* 0x1c */
436  "faultne", /* 0x1d */
437  "faultle", /* 0x1e */
438  "faulto" /* 0x1f */
439  };
440 
441  ssOpcode << mnemonics[opcode - 0x08];
442  if (CTRL_t)
443  ssOpcode << ".f";
444 
445  bool hasDisplacement = opcode < 0x18 && opcode != 0x0a;
446  if (hasDisplacement) {
447  uint32_t disp = CTRL_disp << 2;
448  if (disp & 0x00800000)
449  disp |= 0xff000000;
450 
451  uint32_t addr = vaddr + disp;
452  ssArgs << "0x";
453  ssArgs.flags(std::ios::hex);
454  ssArgs << std::setfill('0') << std::setw(8) << addr;
455  }
456  } else if (opcode >= 0x20 && opcode <= 0x3f) {
457  /* COBR: */
458  const char* mnemonics[] = {
459  "testno", /* 0x20 */
460  "testg", /* 0x21 */
461  "teste", /* 0x22 */
462  "testge", /* 0x23 */
463  "testl", /* 0x24 */
464  "testne", /* 0x25 */
465  "testle", /* 0x26 */
466  "testo", /* 0x27 */
467 
468  "unknown_cobr_0x28", /* 0x28 */
469  "unknown_cobr_0x29", /* 0x29 */
470  "unknown_cobr_0x2a", /* 0x2a */
471  "unknown_cobr_0x2b", /* 0x2b */
472  "unknown_cobr_0x2c", /* 0x2c */
473  "unknown_cobr_0x2d", /* 0x2d */
474  "unknown_cobr_0x2e", /* 0x2e */
475  "unknown_cobr_0x2f", /* 0x2f */
476 
477  "bbc", /* 0x30 */
478  "cmpobg", /* 0x31 */
479  "cmpobe", /* 0x32 */
480  "cmpobge", /* 0x33 */
481  "cmpobl", /* 0x34 */
482  "cmpobne", /* 0x35 */
483  "cmpobne", /* 0x36 */
484  "bbs", /* 0x37 */
485 
486  "cmpibno", /* 0x38 */
487  "cmpibg", /* 0x39 */
488  "cmpibe", /* 0x3a */
489  "cmpibge", /* 0x3b */
490  "cmpibl", /* 0x3c */
491  "cmpibne", /* 0x3d */
492  "cmpible", /* 0x3e */
493  "cmpibo", /* 0x3f */
494  };
495 
496  ssOpcode << mnemonics[opcode - 0x20];
497  if (COBR_t)
498  ssOpcode << ".f";
499 
500  bool src1isBitpos = opcode == 0x30 || opcode == 0x37;
501 
502  if (opcode <= 0x27) {
503  ssArgs << regname_or_literal(COBR_src_dst, 0, COBR_s2);
504  } else {
505  uint32_t targ = COBR_disp << 2;
506  if (targ & 0x00001000)
507  targ |= 0xffffe000;
508  targ += vaddr;
509 
510  ssArgs << regname_or_literal(COBR_src_dst, src1isBitpos ? 1 : COBR_m1, 0) << ",";
511  ssArgs << regname_or_literal(COBR_src_2, 0, COBR_s2) << ",";
512  ssArgs << "0x";
513  ssArgs.flags(std::ios::hex);
514  ssArgs << std::setfill('0') << std::setw(8) << targ;
515  }
516  } else if (opcode >= 0x58 && opcode <= 0x7f) {
517  /* REG: */
518  struct reg_instruction *rinstr = NULL;
519  for (int i = 0; ; ++i) {
520  if (reg_instructions[i].mnemonic == NULL)
521  break;
522  if (reg_instructions[i].opcode == (opcode << 4) + REG_opcode2) {
523  rinstr = &reg_instructions[i];
524  break;
525  }
526  }
527 
528  bool has_src1 = true, has_src2 = true, has_dst = true, has_src3 = false;
529 
530  if (rinstr == NULL) {
531  ssOpcode << "unknown_reg_";
532  ssOpcode.flags(std::ios::hex);
533  ssOpcode << std::setfill('0') << std::setw(2) << opcode;
534  ssOpcode << ":" << std::setw(1) << REG_opcode2;
535  } else {
536  ssOpcode << rinstr->mnemonic;
537  has_src1 = rinstr->has_src1;
538  has_src2 = rinstr->has_src2;
539  has_dst = rinstr->has_dst;
540  has_src3 = rinstr->has_src3;
541  }
542 
543  if (has_src1)
544  ssArgs << regname_or_literal(REG_src1, REG_m1, REG_sfr1);
545 
546  if (has_src2) {
547  if (ssArgs.str().length() > 0)
548  ssArgs << ",";
549  ssArgs << regname_or_literal(REG_src2, REG_m2, REG_sfr2);
550  }
551 
552  if (has_dst) {
553  if (ssArgs.str().length() > 0)
554  ssArgs << ",";
555  if (REG_m3) {
556  /*
557  * The manual for i960CA says (when M3 = 1):
558  *
559  * "src/dst is a literal when used as a source
560  * or a special function register when used
561  * as a destination. M3 may not be 1 when
562  * src/dst is used both as a source and
563  * destination in an instruction (atmod,
564  * modify, extract, modpc)."
565  */
566  if (has_src3)
567  ssArgs << regname_or_literal(REG_src_dst, 1, 0);
568  else
569  ssArgs << regname_or_literal(REG_src_dst, 0, 1);
570  } else
571  ssArgs << regname_or_literal(REG_src_dst, 0, 0);
572  }
573  } else if (opcode >= 0x80 && opcode <= 0xcf) {
574  /* MEM: */
575 
576  /* NOTE: These are for i960CA. When implementing support for
577  other CPU variants, include an enum indicating which CPU
578  it is for so that a warning can be printed for instructions
579  that will cause faults on another CPU. */
580  const char* mnemonics[] = {
581  "ldob", /* 0x80 */
582  "unknown_mem_0x81", /* 0x81 BiiN ldvob */
583  "stob", /* 0x82 */
584  "unknown_mem_0x83", /* 0x83 BiiN stvob */
585  "bx", /* 0x84 */
586  "balx", /* 0x85 */
587  "callx", /* 0x86 */
588  "unknown_mem_0x87", /* 0x87 */
589 
590  "ldos", /* 0x88 */
591  "unknown_mem_0x89", /* 0x89 BiiN ldvos */
592  "stos", /* 0x8a */
593  "unknown_mem_0x8b", /* 0x8b BiiN stvos */
594  "lda", /* 0x8c */
595  "unknown_mem_0x8d", /* 0x8d */
596  "unknown_mem_0x8e", /* 0x8e */
597  "unknown_mem_0x8f", /* 0x8f */
598 
599  "ld", /* 0x90 */
600  "unknown_mem_0x91", /* 0x91 BiiN ldv */
601  "st", /* 0x92 */
602  "unknown_mem_0x93", /* 0x93 Biin stv */
603  "unknown_mem_0x94", /* 0x94 */
604  "unknown_mem_0x95", /* 0x95 */
605  "unknown_mem_0x96", /* 0x96 */
606  "unknown_mem_0x97", /* 0x97 */
607 
608  "ldl", /* 0x98 */
609  "unknown_mem_0x99", /* 0x99 BiiN ldvl */
610  "stl", /* 0x9a */
611  "unknown_mem_0x9b", /* 0x9b BiiN stvl */
612  "unknown_mem_0x9c", /* 0x9c */
613  "unknown_mem_0x9d", /* 0x9d */
614  "unknown_mem_0x9e", /* 0x9e */
615  "unknown_mem_0x9f", /* 0x9f */
616 
617  "ldt", /* 0xa0 */
618  "unknown_mem_0xa1", /* 0xa1 BiiN ldvt */
619  "stt", /* 0xa2 */
620  "unknown_mem_0xa3", /* 0xa3 Biin stvt */
621  "unknown_mem_0xa4", /* 0xa4 */
622  "unknown_mem_0xa5", /* 0xa5 */
623  "unknown_mem_0xa6", /* 0xa6 */
624  "unknown_mem_0xa7", /* 0xa7 */
625 
626  "unknown_mem_0xa8", /* 0xa8 */
627  "unknown_mem_0xa9", /* 0xa9 */
628  "unknown_mem_0xaa", /* 0xaa */
629  "unknown_mem_0xab", /* 0xab */
630  "unknown_mem_0xac", /* 0xac */
631  "unknown_mem_0xad", /* 0xad */
632  "unknown_mem_0xae", /* 0xae */
633  "unknown_mem_0xaf", /* 0xaf */
634 
635  "ldq", /* 0xb0 */
636  "unknown_mem_0xb1", /* 0xb1 BiiN ldvq */
637  "stq", /* 0xb2 */
638  "unknown_mem_0xb3", /* 0xb3 BiiN stvq */
639  "unknown_mem_0xb4", /* 0xb4 */
640  "unknown_mem_0xb5", /* 0xb5 */
641  "unknown_mem_0xb6", /* 0xb6 */
642  "unknown_mem_0xb7", /* 0xb7 */
643 
644  "unknown_mem_0xb8", /* 0xb8 */
645  "unknown_mem_0xb9", /* 0xb9 */
646  "unknown_mem_0xba", /* 0xba */
647  "unknown_mem_0xbb", /* 0xbb */
648  "unknown_mem_0xbc", /* 0xbc */
649  "unknown_mem_0xbd", /* 0xbd */
650  "unknown_mem_0xbe", /* 0xbe */
651  "unknown_mem_0xbf", /* 0xbf */
652 
653  "ldib", /* 0xc0 */
654  "unknown_mem_0xc1", /* 0xc1 BiiN ldvib */
655  "stib", /* 0xc2 */
656  "unknown_mem_0xc3", /* 0xc3 Biin stvib */
657  "unknown_mem_0xc4", /* 0xc4 */
658  "unknown_mem_0xc5", /* 0xc5 */
659  "unknown_mem_0xc6", /* 0xc6 */
660  "unknown_mem_0xc7", /* 0xc7 */
661 
662  "ldis", /* 0xc8 */
663  "unknown_mem_0xc9", /* 0xc9 BiiN ldvis */
664  "stis", /* 0xca */
665  "unknown_mem_0xcb", /* 0xcb BiiN stvis */
666  "unknown_mem_0xcc", /* 0xcc */
667  "unknown_mem_0xcd", /* 0xcd */
668  "unknown_mem_0xce", /* 0xce */
669  "unknown_mem_0xcf", /* 0xcf */
670 
671  /* BiiN:
672  d0 = ldm
673  d1 = ldvm
674  d2 = stm
675  d3 = stvm
676  d8 = ldml
677  d9 = ldvml
678  da = stml
679  db = stvml */
680  };
681 
682  ssOpcode << mnemonics[opcode - 0x80];
683 
684  bool usesDst = opcode != 0x84 && opcode != 0x86;
685  bool isStore = !!(opcode & 2);
686 
687  if (usesDst && isStore) {
688  ssArgs << regname_or_literal(MEMB_src_dst, 0, 0) << ",";
689  }
690 
691  if (iword & 0x1000) {
692  /* MEMB: */
693  int scale = 1 << MEMB_scale;
694  switch (MEMB_mode) {
695  case 0x4:
696  ssArgs << "(" << regname_or_literal(MEMB_abase, 0, 0) << ")";
697  break;
698  case 0x5:
699  {
700  uint32_t offset = displacementWord + 8;
701  ssArgs << "0x";
702  ssArgs.flags(std::ios::hex);
703  ssArgs << std::setfill('0') << std::setw(8) << offset;
704  ssArgs << "(ip)";
705  }
706  break;
707  case 0x7:
708  // (reg1)[reg2 * scale]
709  ssArgs << "(" << regname_or_literal(MEMB_abase, 0, 0) << ")";
710  ssArgs << "[" << regname_or_literal(MEMB_index, 0, 0) << "*" << scale << "]";
711  break;
712  case 0xc:
713  case 0xd:
714  {
715  uint32_t offset = displacementWord;
716  ssArgs << "0x";
717  ssArgs.flags(std::ios::hex);
718  ssArgs << std::setfill('0') << std::setw(8) << offset;
719  if (MEMB_mode == 0xd)
720  ssArgs << "(" << regname_or_literal(MEMB_abase, 0, 0) << ")";
721  }
722  break;
723  case 0xe:
724  case 0xf:
725  {
726  uint32_t offset = displacementWord;
727  ssArgs << "0x";
728  ssArgs.flags(std::ios::hex);
729  ssArgs << std::setfill('0') << std::setw(8) << offset;
730  if (MEMB_mode == 0xf)
731  ssArgs << "(" << regname_or_literal(MEMB_abase, 0, 0) << ")";
732  ssArgs << "[" << regname_or_literal(MEMB_index, 0, 0) << "*" << scale << "]";
733  }
734  break;
735  default:
736  ssArgs << "unimplemented MEMB mode!";
737  }
738  } else {
739  /* MEMA: */
740  ssArgs << "0x";
741  ssArgs.flags(std::ios::hex);
742  ssArgs << std::setfill('0') << std::setw(1) << MEMA_offset;
743 
744  if (MEMA_md)
745  ssArgs << "(" << regname_or_literal(MEMA_abase, 0, 0) << ")";
746  }
747 
748  if (usesDst && !isStore) {
749  ssArgs << "," << regname_or_literal(MEMB_src_dst, 0, 0);
750  }
751  } else if (iword == 0) {
752  ssOpcode << "--";
753  } else {
754  ssOpcode << "unknown_0x";
755  ssOpcode.flags(std::ios::hex);
756  ssOpcode << std::setfill('0') << std::setw(2) << (int)opcode;
757  }
758 
759  result.push_back(ssOpcode.str());
760  result.push_back(ssArgs.str());
761  string comments = ssComments.str();
762  if (comments.length() > 0)
763  result.push_back(comments);
764 
765  return instrSize;
766 }
767 
768 
769 string I960_CPUComponent::GetAttribute(const string& attributeName)
770 {
771  if (attributeName == "stable")
772  return "yes";
773 
774  if (attributeName == "description")
775  return "Intel i960 processor.";
776 
777  return Component::GetAttribute(attributeName);
778 }
779 
780 
781 /*****************************************************************************/
782 
783 
785 {
787  cpu->m_pc = ic->arg[0].u32;
788  cpu->DyntransPCtoPointers();
789 }
790 
791 
793 {
795  REG32(ic->arg[2]) = ic->arg[0].u32;
796  cpu->m_nextIC = ic + 2;
797 }
798 
799 
801 {
802  REG32(ic->arg[2]) = ic->arg[0].u32;
803 }
804 
805 
807 {
809 
810  uint32_t message = REG32(ic->arg[0]);
811  int type = (message >> 8) & 0xff;
812 
813  if (type == 0x01) {
814  // Invalidate cache.
815  // Right now in GXemul, this is a NOP.
816  UI* ui = cpu->GetUI();
817  ui->ShowDebugMessage(cpu, "invalidating cache (no-op for now)");
818  } else {
819 
820  // We didn't actually do anything in this instruction.
821  cpu->m_executedCycles --;
822 
823  // Point to this instruction...
825 
826  // ... and then abort.
827  cpu->m_nextIC = &cpu->m_abortIC;
828 
829  UI* ui = cpu->GetUI();
830  ui->ShowDebugMessage(cpu, "unimplemented sysctl message type");
831  }
832 }
833 
834 
835 /*****************************************************************************/
836 
837 
838 void I960_CPUComponent::Translate(uint32_t iword, uint32_t iword2, struct DyntransIC* ic)
839 {
840  UI* ui = GetUI(); // for debug messages
841 
842  unsigned int opcode = iword >> 24;
843 
844  if (opcode >= 0x08 && opcode <= 0x1f) {
845  /* CTRL: */
846  const int CTRL_disp = (iword >> 2) & 0x3fffff;
847  uint32_t disp = CTRL_disp << 2;
848  if (disp & 0x00800000)
849  disp |= 0xff000000;
850 
851  ic->arg[0].u32 = disp + m_pc;
852 
853  if (opcode == 0x08) {
854  ic->f = instr_b;
855  }
856  } else if (opcode >= 0x58 && opcode <= 0x7f) {
857  /* REG: */
858  const int REG_src_dst = (iword >> 19) & 0x1f;
859  const int REG_src2 = (iword >> 14) & 0x1f;
860  const int REG_m3 = (iword >> 13) & 0x1;
861  const int REG_m2 = (iword >> 12) & 0x1;
862  const int REG_m1 = (iword >> 11) & 0x1;
863  const int REG_opcode2 = (iword >> 7) & 0xf;
864  const int REG_s2 = (iword >> 6) & 0x1;
865  const int REG_s1 = (iword >> 5) & 0x1;
866  const int REG_src1 = (iword >> 0) & 0x1f;
867 
868  int op3 = (opcode << 4) + REG_opcode2;
869 
870  if (REG_m1)
871  ic->arg[0].u32 = REG_src1;
872  else {
873  if (REG_s1)
874  ic->arg[0].p = &m_sfr[REG_src1];
875  else
876  ic->arg[0].p = &m_r[REG_src1];
877  }
878 
879  if (REG_m2)
880  ic->arg[1].u32 = REG_src2;
881  else {
882  if (REG_s2)
883  ic->arg[1].p = &m_sfr[REG_src1];
884  else
885  ic->arg[1].p = &m_r[REG_src2];
886  }
887 
888  if (REG_m3) {
889  // TODO: write to sfr.
890  if (ui != NULL)
891  ui->ShowDebugMessage(this, "unimplemented write to sfr");
892  return;
893  } else {
894  ic->arg[2].p = &m_r[REG_src_dst];
895  }
896 
897  void (*f_lit_lit_reg)(CPUDyntransComponent*, struct DyntransIC*) = NULL;
898  void (*f_lit_reg_reg)(CPUDyntransComponent*, struct DyntransIC*) = NULL;
899  void (*f_reg_lit_reg)(CPUDyntransComponent*, struct DyntransIC*) = NULL;
900  void (*f_reg_reg_reg)(CPUDyntransComponent*, struct DyntransIC*) = NULL;
901 
902  if (op3 == 0x5cc) {
903  // mov NOTE: mov does not use src2.
904  f_lit_lit_reg = instr_mov_lit_reg;
905  f_lit_reg_reg = instr_mov_lit_reg;
906  } else if (op3 == 0x659) {
907  // sysctl
908  f_reg_reg_reg = instr_sysctl;
909  }
910 
911  if (REG_m3 == 0) {
912  if (REG_m1 && REG_m2)
913  ic->f = f_lit_lit_reg;
914  if (REG_m1 && !REG_m2)
915  ic->f = f_lit_reg_reg;
916  if (!REG_m1 && REG_m2)
917  ic->f = f_reg_lit_reg;
918  if (!REG_m1 && !REG_m2)
919  ic->f = f_reg_reg_reg;
920  } else {
921  if (ui != NULL)
922  ui->ShowDebugMessage(this, "unimplemented write to sfr");
923  }
924  } else if (opcode >= 0x80 && opcode <= 0xcf) {
925  /* MEM: */
926  const int MEMA_abase = (iword >> 14) & 0x1f;
927  const int MEMA_md = (iword >> 13) & 0x1;
928  const int MEMA_offset = (iword >> 0) & 0xfff;
929  const int MEMB_src_dst = (iword >> 19) & 0x1f;
930  const int MEMB_abase = (iword >> 14) & 0x1f;
931  const int MEMB_mode = (iword >> 10) & 0xf;
932  const int MEMB_scale = (iword >> 7) & 0x7;
933  const int MEMB_index = (iword >> 0) & 0x1f;
934 
935  ic->arg[2].p = &m_r[MEMB_src_dst];
936 
937  if (iword & 0x1000) {
938  /* MEMB: */
939  switch (MEMB_mode) {
940  case 0xc:
941  ic->arg[0].u32 = iword2;
942  ic->f = instr_lda_displacement;
943  break;
944  default:
945  ui->ShowDebugMessage(this, "unimplemented MEMB_mode");
946  }
947  } else {
948  /* MEMA: */
949  if (MEMA_md)
950  ui->ShowDebugMessage(this, "TODO: MEMA");
951  else {
952  ic->arg[0].u32 = MEMA_offset;
953  ic->f = instr_mov_lit_reg;
954  }
955  }
956  }
957 
958  if (ic->f == NULL && ui != NULL) {
959  stringstream ss;
960  ss.flags(std::ios::hex);
961  ss << "unimplemented opcode 0x" << opcode;
962  ui->ShowDebugMessage(this, ss.str());
963  }
964 }
965 
966 
968 {
970 
971  cpu->DyntransToBeTranslatedBegin(ic);
972 
973  uint32_t iword;
974  if (cpu->DyntransReadInstruction(iword)) {
975  bool readCompleteInstruction = true;
976  uint32_t iword2 = 0;
977  uint32_t opcode = iword >> 24;
978  if (opcode >= 0x80 && opcode <= 0xcf) {
979  /* Only some MEMB instructions have displacement words: */
980  int mode = (iword >> 10) & 0xf;
981  if (mode == 0x5 || mode >= 0xc)
982  readCompleteInstruction = cpu->DyntransReadInstruction(iword2, 4);
983  if (!readCompleteInstruction) {
984  UI* ui = cpu->GetUI();
985  ui->ShowDebugMessage(cpu, "last part of instruction could not be read: TODO");
986  }
987  }
988 
989  if (readCompleteInstruction)
990  cpu->Translate(iword, iword2, ic);
991  }
992 
993  cpu->DyntransToBeTranslatedDone(ic);
994 }
995 
996 
997 /*****************************************************************************/
998 
999 
1000 #ifdef WITHUNITTESTS
1001 
1002 #include "ComponentFactory.h"
1003 
1004 static void Test_I960_CPUComponent_Create()
1005 {
1007  UnitTest::Assert("component was not created?", !cpu.IsNULL());
1008 
1009  const StateVariable * p = cpu->GetVariable("pfp");
1010  UnitTest::Assert("cpu has no pfp state variable?", p != NULL);
1011 }
1012 
1013 static void Test_I960_CPUComponent_Disassembly_Basic()
1014 {
1016  CPUComponent* cpu = i960_cpu->AsCPUComponent();
1017 
1018  vector<string> result;
1019  size_t len;
1020  unsigned char instruction[sizeof(uint32_t) * 2];
1021 
1022  // This assumes that the default endianness is little endian...
1023  instruction[0] = 0x00;
1024  instruction[1] = 0x30;
1025  instruction[2] = 0x68;
1026  instruction[3] = 0x8c;
1027 
1028  instruction[4] = 0x01;
1029  instruction[5] = 0x23;
1030  instruction[6] = 0x34;
1031  instruction[7] = 0x45;
1032 
1033  len = cpu->DisassembleInstruction(0x12345678, sizeof(instruction), instruction, result);
1034 
1035  UnitTest::Assert("disassembled instruction was wrong length?", len, 8);
1036  UnitTest::Assert("disassembly result incomplete?", result.size(), 3);
1037  UnitTest::Assert("disassembly result[0]", result[0], "8c683000 45342301");
1038  UnitTest::Assert("disassembly result[1]", result[1], "lda");
1039  UnitTest::Assert("disassembly result[2]", result[2], "0x45342301,r13");
1040 }
1041 
1042 static GXemul SimpleMachine()
1043 {
1044  GXemul gxemul;
1045  gxemul.GetCommandInterpreter().RunCommand("add mainbus");
1046  gxemul.GetCommandInterpreter().RunCommand("add i960_cpu mainbus0");
1047  gxemul.GetCommandInterpreter().RunCommand("add ram mainbus0");
1048  gxemul.GetCommandInterpreter().RunCommand("ram0.memoryMappedBase = 0x3fe00000");
1049  gxemul.GetCommandInterpreter().RunCommand("ram0.memoryMappedSize = 0x1000");
1050  return gxemul;
1051 }
1052 
1053 static void Test_I960_CPUComponent_Execute_mov()
1054 {
1055  GXemul gxemul = SimpleMachine();
1056  refcount_ptr<Component> cpu = gxemul.GetRootComponent()->LookupPath("root.mainbus0.cpu0");
1057  AddressDataBus* bus = cpu->AsAddressDataBus();
1058 
1059  bus->AddressSelect(0x3fe00048);
1060  bus->WriteData((uint32_t)0x5c201e06, LittleEndian); // mov 6,r4
1061  bus->AddressSelect(0x3fe0004c);
1062  bus->WriteData((uint32_t)0x5c201e06, LittleEndian); // mov 6,r4
1063 
1064  cpu->SetVariableValue("pc", "0x3fe00048");
1065  cpu->SetVariableValue("r4", "0x1234");
1066 
1067  gxemul.SetRunState(GXemul::Running);
1068  gxemul.Execute(1);
1069 
1070  UnitTest::Assert("pc should have increased", cpu->GetVariable("pc")->ToInteger(), 0x3fe0004c);
1071  UnitTest::Assert("r4 should have been modified", cpu->GetVariable("r4")->ToInteger(), 6);
1072 
1073  cpu->SetVariableValue("r4", "0x12345");
1074 
1076  gxemul.Execute(1);
1077 
1078  UnitTest::Assert("pc should have increased again", cpu->GetVariable("pc")->ToInteger(), 0x3fe00050);
1079  UnitTest::Assert("r4 should have been modified again", cpu->GetVariable("r4")->ToInteger(), 6);
1080 }
1081 
1082 static void Test_I960_CPUComponent_Execute_b()
1083 {
1084  GXemul gxemul = SimpleMachine();
1085  refcount_ptr<Component> cpu = gxemul.GetRootComponent()->LookupPath("root.mainbus0.cpu0");
1086  AddressDataBus* bus = cpu->AsAddressDataBus();
1087 
1088  bus->AddressSelect(0x3fe00004);
1089  bus->WriteData((uint32_t)0x080006c0, LittleEndian); // b 0x3fe006c4
1090 
1091  cpu->SetVariableValue("pc", "0x3fe00004");
1092 
1093  gxemul.SetRunState(GXemul::Running);
1094  gxemul.Execute(1);
1095 
1096  UnitTest::Assert("pc should have changed", cpu->GetVariable("pc")->ToInteger(), 0x3fe006c4);
1097 
1098  cpu->SetVariableValue("pc", "0x3fe00004");
1099 
1101  gxemul.Execute(1);
1102 
1103  UnitTest::Assert("pc should have changed again", cpu->GetVariable("pc")->ToInteger(), 0x3fe006c4);
1104 }
1105 
1106 static void Test_I960_CPUComponent_Execute_lda_with_offset()
1107 {
1108  GXemul gxemul = SimpleMachine();
1109  refcount_ptr<Component> cpu = gxemul.GetRootComponent()->LookupPath("root.mainbus0.cpu0");
1110  AddressDataBus* bus = cpu->AsAddressDataBus();
1111 
1112  bus->AddressSelect(0x3fe00010);
1113  bus->WriteData((uint32_t)0x8c180f13, LittleEndian); // lda r3, 0xf13
1114 
1115  cpu->SetVariableValue("pc", "0x3fe00010");
1116  gxemul.SetRunState(GXemul::Running);
1117  gxemul.Execute(1);
1118  UnitTest::Assert("lda length", cpu->GetVariable("pc")->ToInteger(), 0x3fe00014);
1119  UnitTest::Assert("lda", cpu->GetVariable("r3")->ToInteger(), 0xf13);
1120 }
1121 
1122 static void Test_I960_CPUComponent_Execute_lda_with_displacement()
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)0x8cf03000, LittleEndian); // lda
1130  bus->AddressSelect(0x3fe00014);
1131  bus->WriteData((uint32_t)0x3fe0507c, LittleEndian); // 0x3fe0507c, g14
1132 
1133  cpu->SetVariableValue("pc", "0x3fe00010");
1134  gxemul.SetRunState(GXemul::Running);
1135  gxemul.Execute(1);
1136  UnitTest::Assert("lda length", cpu->GetVariable("pc")->ToInteger(), 0x3fe00018);
1137  UnitTest::Assert("lda", cpu->GetVariable("g14")->ToInteger(), 0x3fe0507c);
1138 }
1139 
1141 {
1142  UNITTEST(Test_I960_CPUComponent_Create);
1143  UNITTEST(Test_I960_CPUComponent_Disassembly_Basic);
1144 
1145  UNITTEST(Test_I960_CPUComponent_Execute_mov);
1146  UNITTEST(Test_I960_CPUComponent_Execute_b);
1147  UNITTEST(Test_I960_CPUComponent_Execute_lda_with_offset);
1148  UNITTEST(Test_I960_CPUComponent_Execute_lda_with_displacement);
1149 }
1150 
1151 #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 Sun Sep 30 2018 16:05:18 for GXemul by doxygen 1.8.13