ROSE  0.9.6a
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Registers.C
Go to the documentation of this file.
1 #include "sage3basic.h"
2 #include "Registers.h"
3 
4 std::ostream&
5 operator<<(std::ostream &o, const RegisterDictionary &dict)
6 {
7  dict.print(o);
8  return o;
9 }
10 
11 std::ostream&
12 operator<<(std::ostream &o, const RegisterDescriptor &reg)
13 {
14  reg.print(o);
15  return o;
16 }
17 
18 
19 /*******************************************************************************************************************************
20  * RegisterDescriptor
21  *******************************************************************************************************************************/
22 
23 bool
25 {
26  return majr==other.majr && minr==other.minr && offset==other.offset && nbits==other.nbits;
27 }
28 
29 bool
31 {
32  return !(*this==other);
33 }
34 
35 bool
37 {
38  if (majr!=other.majr)
39  return majr < other.majr;
40  if (minr!=other.minr)
41  return minr < other.minr;
42  if (offset!=other.offset)
43  return offset < other.offset;
44  return nbits < other.nbits;
45 }
46 
47 
48 /*******************************************************************************************************************************
49  * RegisterNames
50  *******************************************************************************************************************************/
51 
52 std::string
53 RegisterNames::operator()(const RegisterDescriptor &rdesc, const RegisterDictionary *dict_/*=NULL*/) const
54 {
55  const RegisterDictionary *dict = dict_ ? dict_ : dflt_dict;
56  if (dict) {
57  std::string name = dict->lookup(rdesc);
58  if (!name.empty())
59  return name;
60  }
61 
62  std::ostringstream ss;
63  ss <<prefix <<rdesc.get_major() <<"." <<rdesc.get_minor();
64  if (show_offset>0 || (show_offset<0 && rdesc.get_offset()!=0))
65  ss <<offset_prefix <<rdesc.get_offset() <<offset_suffix;
66  if (show_size)
67  ss <<size_prefix <<rdesc.get_nbits() <<size_suffix;
68  ss <<suffix;
69  return ss.str();
70 }
71 
72 
73 /*******************************************************************************************************************************
74  * RegisterDictionary
75  *******************************************************************************************************************************/
76 
77 
78 /* class method */
79 uint64_t
81 {
82  uint64_t h = d.get_major() << 24;
83  h ^= d.get_minor() << 16;
84  h ^= d.get_offset() << 8;
85  h ^= d.get_nbits();
86  return h;
87 }
88 
89 void
90 RegisterDictionary::insert(const std::string &name, const RegisterDescriptor &rdesc) {
91  /* Erase the name from the reverse lookup map, indexed by the old descriptor. */
92  Entries::iterator fi = forward.find(name);
93  if (fi!=forward.end()) {
94  Reverse::iterator ri = reverse.find(hash(fi->second));
95  ROSE_ASSERT(ri!=reverse.end());
96  std::vector<std::string>::iterator vi=std::find(ri->second.begin(), ri->second.end(), name);
97  ROSE_ASSERT(vi!=ri->second.end());
98  ri->second.erase(vi);
99  }
100 
101  /* Insert or replace old descriptor with a new one and insert reverse lookup info. */
102  forward[name] = rdesc;
103  reverse[hash(rdesc)].push_back(name);
104 }
105 
106 void
107 RegisterDictionary::insert(const std::string &name, unsigned majr, unsigned minr, unsigned offset, unsigned nbits) {
108  insert(name, RegisterDescriptor(majr, minr, offset, nbits));
109 }
110 
111 void
113  const Entries &entries = other.get_registers();
114  for (Entries::const_iterator ei=entries.begin(); ei!=entries.end(); ++ei)
115  insert(ei->first, ei->second);
116 }
117 
118 void
120  if (other)
121  insert(*other);
122 }
123 
124 const RegisterDescriptor *
125 RegisterDictionary::lookup(const std::string &name) const {
126  Entries::const_iterator fi = forward.find(name);
127  if (fi==forward.end())
128  return NULL;
129  return &(fi->second);
130 }
131 
132 const std::string &
134  Reverse::const_iterator ri = reverse.find(hash(rdesc));
135  if (ri!=reverse.end()) {
136  for (size_t i=ri->second.size(); i>0; --i) {
137  const std::string &name = ri->second[i-1];
138  Entries::const_iterator fi = forward.find(name);
139  ROSE_ASSERT(fi!=forward.end());
140  if (fi->second==rdesc)
141  return name;
142  }
143  }
144 
145  static const std::string empty;
146  return empty;
147 }
148 
149 void
150 RegisterDictionary::resize(const std::string &name, unsigned new_nbits) {
151  const RegisterDescriptor *old_desc = lookup(name);
152  ROSE_ASSERT(old_desc!=NULL);
153  RegisterDescriptor new_desc = *old_desc;
154  new_desc.set_nbits(new_nbits);
155  insert(name, new_desc);
156 }
157 
160  return forward;
161 }
162 
165  return forward;
166 }
167 
170 {
171  const Entries &entries = get_registers();
172  RegisterDescriptors retval;
173  retval.reserve(entries.size());
174  for (Entries::const_iterator ei=entries.begin(); ei!=entries.end(); ++ei)
175  retval.push_back(ei->second);
176  return retval;
177 }
178 
181 {
183  return filter_nonoverlapping(get_descriptors(), order, true);
184 }
185 
188 {
190  return filter_nonoverlapping(get_descriptors(), order, true);
191 }
192 
193 void
194 RegisterDictionary::print(std::ostream &o) const {
195  o <<"RegisterDictionary \"" <<name <<"\" contains " <<forward.size() <<" " <<(1==forward.size()?"entry":"entries") <<"\n";
196  for (Entries::const_iterator ri=forward.begin(); ri!=forward.end(); ++ri)
197  o <<" \"" <<ri->first <<"\" " <<StringUtility::addrToString(hash(ri->second)) <<" " <<ri->second <<"\n";
198 
199  for (Reverse::const_iterator ri=reverse.begin(); ri!=reverse.end(); ++ri) {
200  o <<" " <<StringUtility::addrToString(ri->first);
201  for (std::vector<std::string>::const_iterator vi=ri->second.begin(); vi!=ri->second.end(); ++vi) {
202  o <<" " <<*vi;
203  }
204  o <<"\n";
205  }
206 }
207 
208 // class method
209 const RegisterDictionary *
211 {
212  typedef SgAsmExecutableFileFormat EFF;
213  switch (isa & EFF::ISA_FAMILY_MASK) {
214  case EFF::ISA_IA32_Family:
215  switch (isa) {
216  case EFF::ISA_IA32_286: return dictionary_i286();
217  case EFF::ISA_IA32_386: return dictionary_i386_387(); // assume '387 coprocessor is present
218  case EFF::ISA_IA32_486: return dictionary_i486();
219  case EFF::ISA_IA32_Pentium: return dictionary_pentium();
220  case EFF::ISA_IA32_Pentium4: return dictionary_pentium4();
221  default: return dictionary_pentium4();
222  }
223  break;
224 
225  case EFF::ISA_X8664_Family:
226  return dictionary_amd64();
227 
228  case EFF::ISA_MIPS_Family:
229  return dictionary_mips32_altnames(); // disassembler assumes only dictionary_mips32()
230 
231  case EFF::ISA_ARM_Family:
232  return dictionary_arm7();
233 
234  case EFF::ISA_PowerPC:
235  case EFF::ISA_PowerPC_64bit:
236  return dictionary_powerpc();
237 
238  default:
239  return NULL;
240  }
241 }
242 
243 // class method
244 const RegisterDictionary *
246 {
247  const SgAsmGenericHeaderPtrList &hdrs = interp->get_headers()->get_headers();
248  return hdrs.empty() ? NULL : dictionary_for_isa(hdrs.front()->get_isa());
249 }
250 
260 const RegisterDictionary *
262  static RegisterDictionary *regs = NULL;
263  if (!regs) {
264  regs = new RegisterDictionary("i8086");
265 
266  /* 16-bit general purpose registers. Each has three names depending on which bytes are reference. */
267  regs->insert("al", x86_regclass_gpr, x86_gpr_ax, 0, 8);
268  regs->insert("ah", x86_regclass_gpr, x86_gpr_ax, 8, 8);
269  regs->insert("ax", x86_regclass_gpr, x86_gpr_ax, 0, 16);
270 
271  regs->insert("bl", x86_regclass_gpr, x86_gpr_bx, 0, 8);
272  regs->insert("bh", x86_regclass_gpr, x86_gpr_bx, 8, 8);
273  regs->insert("bx", x86_regclass_gpr, x86_gpr_bx, 0, 16);
274 
275  regs->insert("cl", x86_regclass_gpr, x86_gpr_cx, 0, 8);
276  regs->insert("ch", x86_regclass_gpr, x86_gpr_cx, 8, 8);
277  regs->insert("cx", x86_regclass_gpr, x86_gpr_cx, 0, 16);
278 
279  regs->insert("dl", x86_regclass_gpr, x86_gpr_dx, 0, 8);
280  regs->insert("dh", x86_regclass_gpr, x86_gpr_dx, 8, 8);
281  regs->insert("dx", x86_regclass_gpr, x86_gpr_dx, 0, 16);
282 
283  /* 16-bit segment registers */
284  regs->insert("cs", x86_regclass_segment, x86_segreg_cs, 0, 16);
285  regs->insert("ds", x86_regclass_segment, x86_segreg_ds, 0, 16);
286  regs->insert("ss", x86_regclass_segment, x86_segreg_ss, 0, 16);
287  regs->insert("es", x86_regclass_segment, x86_segreg_es, 0, 16);
288 
289  /* 16-bit pointer registers */
290  regs->insert("sp", x86_regclass_gpr, x86_gpr_sp, 0, 16); /* stack pointer */
291  regs->insert("spl", x86_regclass_gpr, x86_gpr_sp, 0, 8);
292 
293  regs->insert("bp", x86_regclass_gpr, x86_gpr_bp, 0, 16); /* base pointer */
294  regs->insert("bpl", x86_regclass_gpr, x86_gpr_bp, 0, 8);
295 
296  regs->insert("ip", x86_regclass_ip, 0, 0, 16); /* instruction pointer */
297  regs->insert("ipl", x86_regclass_ip, 0, 0, 8);
298 
299  /* Array indexing registers */
300  regs->insert("si", x86_regclass_gpr, x86_gpr_si, 0, 16);
301  regs->insert("sil", x86_regclass_gpr, x86_gpr_si, 0, 8);
302 
303  regs->insert("di", x86_regclass_gpr, x86_gpr_di, 0, 16);
304  regs->insert("dil", x86_regclass_gpr, x86_gpr_di, 0, 8);
305 
306  /* Flags. Reserved flags have no names but can be accessed by reading the entire "flags" register. */
307  regs->insert("flags", x86_regclass_flags, 0, 0, 16); /* all flags */
308  regs->insert("cf", x86_regclass_flags, 0, 0, 1); /* carry status flag */
309  regs->insert("pf", x86_regclass_flags, 0, 2, 1); /* parity status flag */
310  regs->insert("af", x86_regclass_flags, 0, 4, 1); /* adjust status flag */
311  regs->insert("zf", x86_regclass_flags, 0, 6, 1); /* zero status flag */
312  regs->insert("sf", x86_regclass_flags, 0, 7, 1); /* sign status flag */
313  regs->insert("tf", x86_regclass_flags, 0, 8, 1); /* trap system flag */
314  regs->insert("if", x86_regclass_flags, 0, 9, 1); /* interrupt enable system flag */
315  regs->insert("df", x86_regclass_flags, 0, 10, 1); /* direction control flag */
316  regs->insert("of", x86_regclass_flags, 0, 11, 1); /* overflow status flag */
317  regs->insert("nt", x86_regclass_flags, 0, 14, 1); /* nested task system flag */
318  }
319  return regs;
320 }
321 
325 const RegisterDictionary *
327 {
328  static RegisterDictionary *regs = NULL;
329  if (!regs) {
330  regs = new RegisterDictionary("i8088");
331  regs->insert(dictionary_i8086());
332  }
333  return regs;
334 }
335 
339 const RegisterDictionary *
341 {
342  static RegisterDictionary *regs = NULL;
343  if (!regs) {
344  regs = new RegisterDictionary("i286");
345  regs->insert(dictionary_i8086());
346  regs->insert("iopl", x86_regclass_flags, 0, 12, 2); /* I/O privilege level flag */
347  regs->insert("nt", x86_regclass_flags, 0, 14, 1); /* nested task system flag */
348  }
349  return regs;
350 }
351 
358 const RegisterDictionary *
360 {
361  static RegisterDictionary *regs = NULL;
362  if (!regs) {
363  regs = new RegisterDictionary("i386");
364  regs->insert(dictionary_i286());
365 
366  /* Additional 32-bit registers */
367  regs->insert("eax", x86_regclass_gpr, x86_gpr_ax, 0, 32);
368  regs->insert("ebx", x86_regclass_gpr, x86_gpr_bx, 0, 32);
369  regs->insert("ecx", x86_regclass_gpr, x86_gpr_cx, 0, 32);
370  regs->insert("edx", x86_regclass_gpr, x86_gpr_dx, 0, 32);
371  regs->insert("esp", x86_regclass_gpr, x86_gpr_sp, 0, 32);
372  regs->insert("ebp", x86_regclass_gpr, x86_gpr_bp, 0, 32);
373  regs->insert("eip", x86_regclass_ip, 0, 0, 32);
374  regs->insert("esi", x86_regclass_gpr, x86_gpr_si, 0, 32);
375  regs->insert("edi", x86_regclass_gpr, x86_gpr_di, 0, 32);
376  regs->insert("eflags", x86_regclass_flags, 0, 0, 32);
377 
378  /* Additional 16-bit segment registers */
379  regs->insert("fs", x86_regclass_segment, x86_segreg_fs, 0, 16);
380  regs->insert("gs", x86_regclass_segment, x86_segreg_gs, 0, 16);
381 
382  /* Additional flags */
383  regs->insert("rf", x86_regclass_flags, 0, 16, 1); /* resume system flag */
384  regs->insert("vm", x86_regclass_flags, 0, 17, 1); /* virtual 8086 mode flag */
385 
386  /* Control registers */
387  regs->insert("cr0", x86_regclass_cr, 0, 0, 32);
388  regs->insert("cr1", x86_regclass_cr, 1, 0, 32);
389  regs->insert("cr2", x86_regclass_cr, 2, 0, 32);
390  regs->insert("cr3", x86_regclass_cr, 3, 0, 32);
391  regs->insert("cr4", x86_regclass_cr, 4, 0, 32);
392 
393  /* Debug registers */
394  regs->insert("dr0", x86_regclass_dr, 0, 0, 32);
395  regs->insert("dr1", x86_regclass_dr, 1, 0, 32);
396  regs->insert("dr2", x86_regclass_dr, 2, 0, 32);
397  regs->insert("dr3", x86_regclass_dr, 3, 0, 32); /* dr4 and dr5 are reserved */
398  regs->insert("dr6", x86_regclass_dr, 6, 0, 32);
399  regs->insert("dr7", x86_regclass_dr, 7, 0, 32);
400 
401  }
402  return regs;
403 }
404 
406 const RegisterDictionary *
408 {
409  static RegisterDictionary *regs = NULL;
410  if (!regs) {
411  regs = new RegisterDictionary("i386 w/387");
412  regs->insert(dictionary_i386());
413 
414  /* The floating point registers names are relative to the current top-of-stack that changes dynamically. The
415  * definitions we're creating here are static. When a floating-point instruction is simulated (e.g., by the
416  * instruction semantics analyses) then the simulation will have to make adjustments to the storage descriptors in
417  * order for the register names to point to their new storage locations. */
418  regs->insert("st(0)", x86_regclass_st, 0, 0, 80);
419  regs->insert("st(1)", x86_regclass_st, 1, 0, 80);
420  regs->insert("st(2)", x86_regclass_st, 2, 0, 80);
421  regs->insert("st(3)", x86_regclass_st, 3, 0, 80);
422  regs->insert("st(4)", x86_regclass_st, 4, 0, 80);
423  regs->insert("st(5)", x86_regclass_st, 5, 0, 80);
424  regs->insert("st(6)", x86_regclass_st, 6, 0, 80);
425  regs->insert("st(7)", x86_regclass_st, 7, 0, 80);
426  }
427  return regs;
428 }
429 
430 
434 const RegisterDictionary *
436 {
437  static RegisterDictionary *regs = NULL;
438  if (!regs) {
439  regs = new RegisterDictionary("i486");
440  regs->insert(dictionary_i386_387());
441  regs->insert("ac", x86_regclass_flags, 0, 18, 1); /* alignment check system flag */
442  }
443  return regs;
444 }
445 
449 const RegisterDictionary *
451 {
452  static RegisterDictionary *regs = NULL;
453  if (!regs) {
454  regs = new RegisterDictionary("pentium");
455  regs->insert(dictionary_i486());
456 
457  /* Additional flags */
458  regs->insert("vif", x86_regclass_flags, 0, 19, 1); /* virtual interrupt flag */
459  regs->insert("vip", x86_regclass_flags, 0, 20, 1); /* virt interrupt pending */
460  regs->insert("id", x86_regclass_flags, 0, 21, 1); /* ident system flag */
461 
462  /* The MMi registers are aliases for the ST(i) registers but are absolute rather than relative to the top of the
463  * stack. We're creating the static definitions, so MMi will point to the same storage as ST(i) for 0<=i<=7. Note that
464  * a write to one of the 64-bit MMi registers causes the high-order 16 bits of the corresponding ST(j) register to be
465  * set to all ones to indicate a NaN value. */
466  regs->insert("mm0", x86_regclass_mm, 0, 0, 64);
467  regs->insert("mm1", x86_regclass_mm, 1, 0, 64);
468  regs->insert("mm2", x86_regclass_mm, 2, 0, 64);
469  regs->insert("mm3", x86_regclass_mm, 3, 0, 64);
470  regs->insert("mm4", x86_regclass_mm, 4, 0, 64);
471  regs->insert("mm5", x86_regclass_mm, 5, 0, 64);
472  regs->insert("mm6", x86_regclass_mm, 6, 0, 64);
473  regs->insert("mm7", x86_regclass_mm, 7, 0, 64);
474  }
475  return regs;
476 }
477 
482 const RegisterDictionary *
484 {
485  static RegisterDictionary *regs = NULL;
486  if (!regs) {
487  regs = new RegisterDictionary("pentium4");
488  regs->insert(dictionary_pentium());
489  regs->insert("xmm0", x86_regclass_xmm, 0, 0, 128);
490  regs->insert("xmm1", x86_regclass_xmm, 1, 0, 128);
491  regs->insert("xmm2", x86_regclass_xmm, 2, 0, 128);
492  regs->insert("xmm3", x86_regclass_xmm, 3, 0, 128);
493  regs->insert("xmm4", x86_regclass_xmm, 4, 0, 128);
494  regs->insert("xmm5", x86_regclass_xmm, 5, 0, 128);
495  regs->insert("xmm6", x86_regclass_xmm, 6, 0, 128);
496  regs->insert("xmm7", x86_regclass_xmm, 7, 0, 128);
497  }
498  return regs;
499 }
500 
501 
512 const RegisterDictionary *
514 {
515  static RegisterDictionary *regs = NULL;
516  if (!regs) {
517  regs = new RegisterDictionary("amd64");
518  regs->insert(dictionary_pentium4());
519 
520  /* Additional 64-bit (and hi-end 32-bit) registers */
521  regs->insert("rax", x86_regclass_gpr, x86_gpr_ax, 0, 64);
522  regs->insert("rbx", x86_regclass_gpr, x86_gpr_bx, 0, 64);
523  regs->insert("rcx", x86_regclass_gpr, x86_gpr_cx, 0, 64);
524  regs->insert("rdx", x86_regclass_gpr, x86_gpr_dx, 0, 64);
525  regs->insert("rsp", x86_regclass_gpr, x86_gpr_sp, 0, 64);
526  regs->insert("rbp", x86_regclass_gpr, x86_gpr_bp, 0, 64);
527  regs->insert("rsi", x86_regclass_gpr, x86_gpr_si, 0, 64);
528  regs->insert("rdi", x86_regclass_gpr, x86_gpr_di, 0, 64);
529  regs->insert("rip", x86_regclass_ip, 0, 0, 64);
530  regs->insert("rflags", x86_regclass_flags, 0, 0, 64);
531 
532  for (unsigned i=8; i<16; i++) {
533  /* New general purpose registers in various widths */
534  std::string name = "r" + StringUtility::numberToString(i);
535  regs->insert(name, x86_regclass_gpr, i, 0, 64);
536  regs->insert(name+"b", x86_regclass_gpr, i, 0, 8);
537  regs->insert(name+"w", x86_regclass_gpr, i, 0, 16);
538  regs->insert(name+"d", x86_regclass_gpr, i, 0, 32);
539 
540  /* New media XMM registers */
541  regs->insert(std::string("xmm")+StringUtility::numberToString(i),
542  x86_regclass_xmm, i, 0, 128);
543  }
544 
545  /* Control registers become 64 bits, and cr8 is added */
546  regs->resize("cr0", 64);
547  regs->resize("cr1", 64);
548  regs->resize("cr2", 64);
549  regs->resize("cr3", 64);
550  regs->resize("cr4", 64);
551  regs->insert("cr8", x86_regclass_cr, 8, 0, 64);
552 
553  /* Debug registers become 64 bits */
554  regs->resize("dr0", 64);
555  regs->resize("dr1", 64);
556  regs->resize("dr2", 64);
557  regs->resize("dr3", 64); /* dr4 and dr5 are reserved */
558  regs->resize("dr6", 64);
559  regs->resize("dr7", 64);
560  }
561  return regs;
562 }
563 
575 const RegisterDictionary *
577  /* Documentation of the Nintendo GameBoy Advance is pretty decent. It's located here:
578  * http:// nocash.emubase.de/gbatek.htm */
579  static RegisterDictionary *regs = NULL;
580  if (!regs) {
581  regs = new RegisterDictionary("arm7");
582 
583  /* The (up-to) 16 general purpose registers available within the current mode. */
584  for (unsigned i=0; i<16; i++)
585  regs->insert("r"+StringUtility::numberToString(i), arm_regclass_gpr, i, 0, 32);
586 
587  /* The (up to) two status registers available within the current mode. */
588  regs->insert("cpsr", arm_regclass_psr, arm_psr_current, 0, 32); /* current program status register */
589  regs->insert("spsr", arm_regclass_psr, arm_psr_saved, 0, 32); /* saved program status register */
590 
591  /* Individual parts of the cpsr register */
592  regs->insert("cpsr_m", arm_regclass_psr, arm_psr_current, 0, 5); /* Mode bits indicating current operating mode */
593  regs->insert("cpsr_t", arm_regclass_psr, arm_psr_current, 5, 1); /* State bit (0=>ARM; 1=>THUMB) */
594  regs->insert("cpsr_f", arm_regclass_psr, arm_psr_current, 6, 1); /* FIQ disable (0=>enable; 1=>disable) */
595  regs->insert("cpsr_i", arm_regclass_psr, arm_psr_current, 7, 1); /* IRQ disable (0=>enable; 1=>disable) */
596  regs->insert("cpsr_q", arm_regclass_psr, arm_psr_current, 27, 1); /* sticky overflow (ARMv5TE and up only) */
597  regs->insert("cpsr_v", arm_regclass_psr, arm_psr_current, 28, 1); /* overflow flag (0=>no overflow; 1=overflow) */
598  regs->insert("cpsr_c", arm_regclass_psr, arm_psr_current, 29, 1); /* carry flag (1=>no carry; 1=>carry) */
599  regs->insert("cpsr_z", arm_regclass_psr, arm_psr_current, 30, 1); /* zero flag (0=>not zero; 1=>zero) */
600  regs->insert("cpsr_n", arm_regclass_psr, arm_psr_current, 31, 1); /* sign flag (0=>not signed; 1=>signed) */
601 
602  /* The six spsr registers (at most one available depending on the operating mode), have the same bit fields as the cpsr
603  * register. When an exception occurs, the current status (in cpsr) is copied to one of the spsr registers. */
604  regs->insert("spsr_m", arm_regclass_psr, arm_psr_saved, 0, 5); /* Mode bits indicating saved operating mode */
605  regs->insert("spsr_t", arm_regclass_psr, arm_psr_saved, 5, 1); /* State bit (0=>ARM; 1=>THUMB) */
606  regs->insert("spsr_f", arm_regclass_psr, arm_psr_saved, 6, 1); /* FIQ disable (0=>enable; 1=>disable) */
607  regs->insert("spsr_i", arm_regclass_psr, arm_psr_saved, 7, 1); /* IRQ disable (0=>enable; 1=>disable) */
608  regs->insert("spsr_q", arm_regclass_psr, arm_psr_saved, 27, 1); /* sticky overflow (ARMv5TE and up only) */
609  regs->insert("spsr_v", arm_regclass_psr, arm_psr_saved, 28, 1); /* overflow flag (0=>no overflow; 1=overflow) */
610  regs->insert("spsr_c", arm_regclass_psr, arm_psr_saved, 29, 1); /* carry flag (1=>no carry; 1=>carry) */
611  regs->insert("spsr_z", arm_regclass_psr, arm_psr_saved, 30, 1); /* zero flag (0=>not zero; 1=>zero) */
612  regs->insert("spsr_n", arm_regclass_psr, arm_psr_saved, 31, 1); /* sign flag (0=>not signed; 1=>signed) */
613  }
614  return regs;
615 }
616 
618 const RegisterDictionary *
620 {
621  static RegisterDictionary *regs = NULL;
622  if (!regs) {
623  regs = new RegisterDictionary("powerpc");
624 
625  /**********************************************************************************************************************
626  * General purpose and floating point registers
627  **********************************************************************************************************************/
628  for (unsigned i=0; i<32; i++) {
629  regs->insert("r"+StringUtility::numberToString(i), powerpc_regclass_gpr, i, 0, 32);
630  regs->insert("f"+StringUtility::numberToString(i), powerpc_regclass_fpr, i, 0, 64);
631  }
632 
633  /**********************************************************************************************************************
634  * State, status, condition, control registers
635  **********************************************************************************************************************/
636 
637  /* Machine state register */
638  regs->insert("msr", powerpc_regclass_msr, 0, 0, 32);
639 
640  /* Floating point status and control register */
641  regs->insert("fpscr", powerpc_regclass_fpscr, 0, 0, 32);
642 
643  /* Condition Register. This register is grouped into eight fields, where each field is 4 bits. Many PowerPC
644  * instructions define bit 31 of the instruction encoding as the Rc bit, and some instructions imply an Rc value equal
645  * to 1. When Rc is equal to 1 for integer operations, the CR field 0 is set to reflect the result of the instruction's
646  * operation: Equal (EQ), Greater Than (GT), Less Than (LT), and Summary Overflow (SO). When Rc is equal to 1 for
647  * floating-point operations, the CR field 1 is set to reflect the state of the exception status bits in the FPSCR: FX,
648  * FEX, VX, and OX. Any CR field can be the target of an integer or floating-point comparison instruction. The CR field
649  * 0 is also set to reflect the result of a conditional store instruction (stwcx or stdcx). There is also a set of
650  * instructions that can manipulate a specific CR bit, a specific CR field, or the entire CR, usually to combine
651  * several conditions into a single bit for testing. */
652  regs->insert("cr", powerpc_regclass_cr, 0, 0, 32);
653  for (unsigned i=0; i<32; i++) {
654  switch (i%4) {
655  case 0:
656  regs->insert("cr"+StringUtility::numberToString(i/4), powerpc_regclass_cr, 0, i, 4);
657  regs->insert("cr"+StringUtility::numberToString(i/4)+"*4+lt", powerpc_regclass_cr, 0, i, 1);
658  break;
659  case 1:
660  regs->insert("cr"+StringUtility::numberToString(i/4)+"*4+gt", powerpc_regclass_cr, 0, i, 1);
661  break;
662  case 2:
663  regs->insert("cr"+StringUtility::numberToString(i/4)+"*4+eq", powerpc_regclass_cr, 0, i, 1);
664  break;
665  case 3:
666  regs->insert("cr"+StringUtility::numberToString(i/4)+"*4+so", powerpc_regclass_cr, 0, i, 1);
667  break;
668  }
669  }
670 
671  /* The processor version register is a 32-bit read-only register that identifies the version and revision level of the
672  * processor. Processor versions are assigned by the PowerPC architecture process. Revision levels are implementation
673  * defined. Access to the register is privileged, so that an application program can determine the processor version
674  * only with the help of an operating system function. */
675  regs->insert("pvr", powerpc_regclass_pvr, 0, 0, 32);
676 
677  /**********************************************************************************************************************
678  * The instruction address register is a pseudo register. It is not directly available to the user other than through a
679  * "branch and link" instruction. It is primarily used by debuggers to show the next instruction to be executed.
680  **********************************************************************************************************************/
681  regs->insert("iar", powerpc_regclass_iar, 0, 0, 32);
682 
683  /**********************************************************************************************************************
684  * Special purpose registers. There are 1024 of these, some of which have special names. We name all 1024 consistently
685  * and create aliases for the special ones. This allows the disassembler to look them up generically. Because the
686  * special names appear after the generic names, a reverse lookup will return the special name.
687  **********************************************************************************************************************/
688  /* Generic names for them all */
689  for (unsigned i=0; i<1024; i++)
690  regs->insert("spr"+StringUtility::numberToString(i), powerpc_regclass_spr, i, 0, 32);
691 
692  /* The link register contains the address to return to at the end of a function call. Each branch instruction encoding
693  * has an LK bit. If the LK bit is 1, the branch instruction moves the program counter to the link register. Also, the
694  * conditional branch instruction BCLR branches to the value in the link register. */
695  regs->insert("lr", powerpc_regclass_spr, powerpc_spr_lr, 0, 32);
696 
697  /* The fixed-point exception register contains carry and overflow information from integer arithmetic operations. It
698  * also contains carry input to certain integer arithmetic operations and the number of bytes to transfer during load
699  * and store string instructions, lswx and stswx. */
700  regs->insert("xer", powerpc_regclass_spr, powerpc_spr_xer, 0, 32);
701 
702  /* The count register contains a loop counter that is decremented on certain branch operations. Also, the conditional
703  * branch instruction bcctr branches to the value in the CTR. */
704  regs->insert("ctr", powerpc_regclass_spr, powerpc_spr_ctr, 0, 32);
705 
706  /* Other special purpose registers. */
707  regs->insert("dsisr", powerpc_regclass_spr, powerpc_spr_dsisr, 0, 32);
708  regs->insert("dar", powerpc_regclass_spr, powerpc_spr_dar, 0, 32);
709  regs->insert("dec", powerpc_regclass_spr, powerpc_spr_dec, 0, 32);
710 
711  /**********************************************************************************************************************
712  * Time base registers. There are 1024 of these, some of which have special names. We name all 1024 consistently and
713  * create aliases for the special ones. This allows the disassembler to look them up generically. Because the special
714  * names appear after the generic names, a reverse lookup will return the special name.
715  **********************************************************************************************************************/
716  for (unsigned i=0; i<1024; i++)
717  regs->insert("tbr"+StringUtility::numberToString(i), powerpc_regclass_tbr, i, 0, 32);
718 
719  regs->insert("tbl", powerpc_regclass_tbr, powerpc_tbr_tbl, 0, 32); /* time base lower */
720  regs->insert("tbu", powerpc_regclass_tbr, powerpc_tbr_tbu, 0, 32); /* time base upper */
721  }
722  return regs;
723 }
724 
728 const RegisterDictionary *
730 {
731  static RegisterDictionary *regs = NULL;
732  if (!regs) {
733  regs = new RegisterDictionary("mips32");
734 
735  // 32 general purpose registers
736  for (size_t i=0; i<32; ++i)
737  regs->insert("r"+StringUtility::numberToString(i), mips_regclass_gpr, i, 0, 32);
738 
739  // Alternate names for the general purpose registers
740  regs->insert("zero", mips_regclass_gpr, 0, 0, 32); // always equal to zero
741  regs->insert("at", mips_regclass_gpr, 1, 0, 32); // assembler temporary
742  regs->insert("v0", mips_regclass_gpr, 2, 0, 32); // return value from a function call
743  regs->insert("v1", mips_regclass_gpr, 3, 0, 32);
744  regs->insert("a0", mips_regclass_gpr, 4, 0, 32); // first four function arguments
745  regs->insert("a1", mips_regclass_gpr, 5, 0, 32);
746  regs->insert("a2", mips_regclass_gpr, 6, 0, 32);
747  regs->insert("a3", mips_regclass_gpr, 7, 0, 32);
748  regs->insert("t0", mips_regclass_gpr, 8, 0, 32); // temporary variables; need not be preserved
749  regs->insert("t1", mips_regclass_gpr, 9, 0, 32);
750  regs->insert("t2", mips_regclass_gpr, 10, 0, 32);
751  regs->insert("t3", mips_regclass_gpr, 11, 0, 32);
752  regs->insert("t4", mips_regclass_gpr, 12, 0, 32);
753  regs->insert("t5", mips_regclass_gpr, 13, 0, 32);
754  regs->insert("t6", mips_regclass_gpr, 14, 0, 32);
755  regs->insert("t7", mips_regclass_gpr, 15, 0, 32);
756  regs->insert("s0", mips_regclass_gpr, 16, 0, 32); // temporary variables; must be preserved
757  regs->insert("s1", mips_regclass_gpr, 17, 0, 32);
758  regs->insert("s2", mips_regclass_gpr, 18, 0, 32);
759  regs->insert("s3", mips_regclass_gpr, 19, 0, 32);
760  regs->insert("s4", mips_regclass_gpr, 20, 0, 32);
761  regs->insert("s5", mips_regclass_gpr, 21, 0, 32);
762  regs->insert("s6", mips_regclass_gpr, 22, 0, 32);
763  regs->insert("s7", mips_regclass_gpr, 23, 0, 32);
764  regs->insert("t8", mips_regclass_gpr, 24, 0, 32); // two more temporaries; need not be preserved
765  regs->insert("t9", mips_regclass_gpr, 25, 0, 32);
766  regs->insert("k0", mips_regclass_gpr, 26, 0, 32); // kernel use; may change unexpectedly
767  regs->insert("k1", mips_regclass_gpr, 27, 0, 32);
768  regs->insert("gp", mips_regclass_gpr, 28, 0, 32); // global pointer
769  regs->insert("sp", mips_regclass_gpr, 29, 0, 32); // stack pointer
770  regs->insert("s8", mips_regclass_gpr, 30, 0, 32); // temp; must be preserved (or "fp")
771  regs->insert("fp", mips_regclass_gpr, 30, 0, 32); // stack frame pointer (or "s8")
772  regs->insert("ra", mips_regclass_gpr, 31, 0, 32); // return address (link register)
773 
774  // Special purpose registers
775  regs->insert("hi", mips_regclass_spr, mips_spr_hi, 0, 32);
776  regs->insert("lo", mips_regclass_spr, mips_spr_lo, 0, 32);
777  regs->insert("pc", mips_regclass_spr, mips_spr_pc, 0, 32); // program counter
778 
779  // 32 floating point registers
780  for (size_t i=0; i<32; ++i)
781  regs->insert("f"+StringUtility::numberToString(i), mips_regclass_fpr, i, 0, 32);
782 
783  // Five FPU control registers are used to identify and control the FPU. The FCCR, FEXR, and FENR are portions
784  // (not necessarily contiguous) of the FCSR extended to 32 bits, and therefore all share a major number.
785  regs->insert("fir", mips_regclass_spr, mips_spr_fir, 0, 32); // FP implementation and revision
786  regs->insert("fcsr", mips_regclass_fcsr, mips_fcsr_all, 0, 32); // the entire FCSR register
787  regs->insert("fccr", mips_regclass_fcsr, mips_fcsr_fccr, 0, 32); // condition codes portion of FCSR
788  regs->insert("fexr", mips_regclass_fcsr, mips_fcsr_fexr, 0, 32); // FP exceptions
789  regs->insert("fenr", mips_regclass_fcsr, mips_fcsr_fenr, 0, 32); // FP enables
790 
791  // parts of the FIR (only those defined for MIPS32 release 1)
792  regs->insert("fir.d", mips_regclass_spr, mips_spr_fir, 17, 1); // is double-precision implemented?
793  regs->insert("fir.s", mips_regclass_spr, mips_spr_fir, 16, 1); // is single-precision implemented?
794  regs->insert("fir.processorid", mips_regclass_spr, mips_spr_fir, 8, 8); // identifies the FP processor
795  regs->insert("fir.revision", mips_regclass_spr, mips_spr_fir, 0, 8); // FP unit revision number
796 
797  // Additional registers for coprocessor 0 are not part of this dictionary. They use major number mips_regclass_cp0gpr.
798 
799  // Additional implementation-specific coprocessor 2 registers are not part of the dictionary. Coprocessor 2 may have up
800  // to 32 general purpose registers and up to 32 control registers. They use the major numbers mips_regclass_cp2gpr and
801  // mips_regclass_cp2spr.
802  }
803  return regs;
804 }
805 
812 const RegisterDictionary *
814 {
815  static RegisterDictionary *regs = NULL;
816  if (!regs) {
817  regs = new RegisterDictionary("mips32");
818  regs->insert(dictionary_mips32());
819 
820  // Alternate names for the general purpose registers
821  regs->insert("zero", mips_regclass_gpr, 0, 0, 32); // always equal to zero
822  regs->insert("at", mips_regclass_gpr, 1, 0, 32); // assembler temporary
823  regs->insert("v0", mips_regclass_gpr, 2, 0, 32); // return value from a function call
824  regs->insert("v1", mips_regclass_gpr, 3, 0, 32);
825  regs->insert("a0", mips_regclass_gpr, 4, 0, 32); // first four function arguments
826  regs->insert("a1", mips_regclass_gpr, 5, 0, 32);
827  regs->insert("a2", mips_regclass_gpr, 6, 0, 32);
828  regs->insert("a3", mips_regclass_gpr, 7, 0, 32);
829  regs->insert("t0", mips_regclass_gpr, 8, 0, 32); // temporary variables; need not be preserved
830  regs->insert("t1", mips_regclass_gpr, 9, 0, 32);
831  regs->insert("t2", mips_regclass_gpr, 10, 0, 32);
832  regs->insert("t3", mips_regclass_gpr, 11, 0, 32);
833  regs->insert("t4", mips_regclass_gpr, 12, 0, 32);
834  regs->insert("t5", mips_regclass_gpr, 13, 0, 32);
835  regs->insert("t6", mips_regclass_gpr, 14, 0, 32);
836  regs->insert("t7", mips_regclass_gpr, 15, 0, 32);
837  regs->insert("s0", mips_regclass_gpr, 16, 0, 32); // temporary variables; must be preserved
838  regs->insert("s1", mips_regclass_gpr, 17, 0, 32);
839  regs->insert("s2", mips_regclass_gpr, 18, 0, 32);
840  regs->insert("s3", mips_regclass_gpr, 19, 0, 32);
841  regs->insert("s4", mips_regclass_gpr, 20, 0, 32);
842  regs->insert("s5", mips_regclass_gpr, 21, 0, 32);
843  regs->insert("s6", mips_regclass_gpr, 22, 0, 32);
844  regs->insert("s7", mips_regclass_gpr, 23, 0, 32);
845  regs->insert("t8", mips_regclass_gpr, 24, 0, 32); // two more temporaries; need not be preserved
846  regs->insert("t9", mips_regclass_gpr, 25, 0, 32);
847  regs->insert("k0", mips_regclass_gpr, 26, 0, 32); // kernel use; may change unexpectedly
848  regs->insert("k1", mips_regclass_gpr, 27, 0, 32);
849  regs->insert("gp", mips_regclass_gpr, 28, 0, 32); // global pointer
850  regs->insert("sp", mips_regclass_gpr, 29, 0, 32); // stack pointer
851  regs->insert("s8", mips_regclass_gpr, 30, 0, 32); // temp; must be preserved (or "fp")
852  regs->insert("fp", mips_regclass_gpr, 30, 0, 32); // stack frame pointer (or "s8")
853  regs->insert("ra", mips_regclass_gpr, 31, 0, 32); // return address (link register)
854  }
855  return regs;
856 }
857