HPCToolkit
IA64ISA.cpp
Go to the documentation of this file.
1 // -*-Mode: C++;-*-
2 
3 // * BeginRiceCopyright *****************************************************
4 //
5 // $HeadURL$
6 // $Id$
7 //
8 // --------------------------------------------------------------------------
9 // Part of HPCToolkit (hpctoolkit.org)
10 //
11 // Information about sources of support for research and development of
12 // HPCToolkit is at 'hpctoolkit.org' and in 'README.Acknowledgments'.
13 // --------------------------------------------------------------------------
14 //
15 // Copyright ((c)) 2002-2019, Rice University
16 // All rights reserved.
17 //
18 // Redistribution and use in source and binary forms, with or without
19 // modification, are permitted provided that the following conditions are
20 // met:
21 //
22 // * Redistributions of source code must retain the above copyright
23 // notice, this list of conditions and the following disclaimer.
24 //
25 // * Redistributions in binary form must reproduce the above copyright
26 // notice, this list of conditions and the following disclaimer in the
27 // documentation and/or other materials provided with the distribution.
28 //
29 // * Neither the name of Rice University (RICE) nor the names of its
30 // contributors may be used to endorse or promote products derived from
31 // this software without specific prior written permission.
32 //
33 // This software is provided by RICE and contributors "as is" and any
34 // express or implied warranties, including, but not limited to, the
35 // implied warranties of merchantability and fitness for a particular
36 // purpose are disclaimed. In no event shall RICE or contributors be
37 // liable for any direct, indirect, incidental, special, exemplary, or
38 // consequential damages (including, but not limited to, procurement of
39 // substitute goods or services; loss of use, data, or profits; or
40 // business interruption) however caused and on any theory of liability,
41 // whether in contract, strict liability, or tort (including negligence
42 // or otherwise) arising in any way out of the use of this software, even
43 // if advised of the possibility of such damage.
44 //
45 // ******************************************************* EndRiceCopyright *
46 
47 //***************************************************************************
48 //
49 // File:
50 // $HeadURL$
51 //
52 // Purpose:
53 // [The purpose of this file]
54 //
55 // Description:
56 // [The set of functions, macros, etc. defined in the file]
57 //
58 //***************************************************************************
59 
60 //************************* System Include Files ****************************
61 
62 #include <iostream>
63 using std::ostream;
64 
65 #include <cstdarg>
66 #include <cstring> // for 'memcpy'
67 
68 //*************************** User Include Files ****************************
69 
70 #include <include/gnu_dis-asm.h>
71 
72 #include "IA64ISA.hpp"
73 
75 
76 //*************************** Forward Declarations ***************************
77 
78 //****************************************************************************
79 
80 static MachInsn*
82 {
83  // Do not change; the GNU decoders depend upon these particular
84  // offsets. Note that the offsets do not actually match the IA64
85  // template [5,41,41,41].
86  DIAG_Assert(opIndex <= 2, "Programming Error");
87  return (MachInsn*)((MachInsnByte*)mi + (6 * opIndex)); // 0, 6, 12
88 }
89 
90 
91 static VMA
92 GNUvma2vma(bfd_vma di_vma, MachInsn* GCC_ATTR_UNUSED insn_addr, VMA insn_vma)
93 {
94  VMA x = (VMA)di_vma + insn_vma;
95  return x;
96 }
97 
98 
99 static void
100 GNUbu_print_addr(bfd_vma di_vma, struct disassemble_info* di)
101 {
102  GNUbu_disdata* data = (GNUbu_disdata*)di->application_data;
103 
104  VMA x = GNUvma2vma(di_vma, data->insn_addr, data->insn_vma);
105  ostream* os = (ostream*)di->stream;
106  *os << std::showbase << std::hex << x << std::dec;
107 }
108 
109 
110 //****************************************************************************
111 // IA64ISA
112 //****************************************************************************
113 
115  : m_di(NULL), m_di_dis(NULL)
116 {
117  // See 'dis-asm.h'
118  m_di = new disassemble_info;
119  init_disassemble_info(m_di, stdout, GNUbu_fprintf_stub);
120  m_di->arch = bfd_arch_ia64; // bfd_get_arch (abfd);
121  m_di->endian = BFD_ENDIAN_LITTLE;
122  m_di->read_memory_func = GNUbu_read_memory; // vs. 'buffer_read_memory'
123  m_di->print_address_func = GNUbu_print_addr_stub; // vs. 'generic_print_addr'
124 
125  m_di_dis = new disassemble_info;
126  init_disassemble_info(m_di_dis, stdout, GNUbu_fprintf);
127  m_di_dis->application_data = (void*)&m_dis_data;
128  m_di_dis->arch = m_di->arch;
129  m_di_dis->endian = m_di->endian;
130  m_di_dis->read_memory_func = GNUbu_read_memory;
131  m_di_dis->print_address_func = GNUbu_print_addr;
132 }
133 
134 
136 {
137  delete m_di;
138  delete m_di_dis;
139 }
140 
141 
144 {
145  MachInsn* gnuMI = ConvertMIToOpMI(mi, opIndex);
146  InsnDesc d;
147 
148  if (cacheLookup(gnuMI) == NULL) {
149  int size = print_insn_ia64(PTR_TO_BFDVMA(gnuMI), m_di);
150  cacheSet(gnuMI, (ushort)size);
151  }
152 
153  switch(m_di->insn_type) {
154  case dis_noninsn:
156  break;
157  case dis_branch:
158  if (m_di->target != 0) {
160  }
161  else {
163  }
164  break;
165  case dis_condbranch:
166  // N.B.: On the Itanium it is possible to have a one-bundle loop
167  // (where the third slot branches to the first slot)!
168  if (m_di->target != 0 || opIndex != 0) {
169  d.set(InsnDesc::INT_BR_COND_REL); // arbitrarily choose int
170  }
171  else {
172  d.set(InsnDesc::INT_BR_COND_IND); // arbitrarily choose int
173  }
174  break;
175  case dis_jsr:
176  if (m_di->target != 0) {
178  }
179  else {
181  }
182  break;
183  case dis_condjsr:
184  d.set(InsnDesc::OTHER);
185  break;
186  case dis_return:
188  break;
189  case dis_dref:
190  case dis_dref2:
192  break;
193  default:
194  d.set(InsnDesc::OTHER);
195  break;
196  }
197  return d;
198 }
199 
200 
201 VMA
204 {
205  MachInsn* gnuMI = ConvertMIToOpMI(mi, opIndex);
206 
207  if (cacheLookup(gnuMI) == NULL) {
208  int size = print_insn_ia64(PTR_TO_BFDVMA(gnuMI), m_di);
209  cacheSet(gnuMI, (ushort)size);
210  }
211 
212  // The target field is only set on instructions with targets.
213  // N.B.: On the Itanium it is possible to have a one-bundle loop
214  // (where the third slot branches to the first slot)!
215  if (m_di->target != 0 || opIndex != 0) {
216  return GNUvma2vma(m_di->target, mi, vma);
217  }
218  else {
219  return 0;
220  }
221 }
222 
223 
224 ushort
226 {
227  // Because of the MLX template and data, we can't just return 3 here.
228  if (cacheLookup(mi) == NULL) {
229  int size = print_insn_ia64(PTR_TO_BFDVMA(mi), m_di);
230  cacheSet(mi, (ushort)size);
231  }
232 
233  return (ushort)(m_di->target2);
234 }
235 
236 
237 void
238 IA64ISA::decode(ostream& os, MachInsn* mi, VMA vma,
239  ushort GCC_ATTR_UNUSED opIndex)
240 {
242  m_dis_data.insn_vma = vma;
243 
244  m_di_dis->stream = (void*)&os;
245  print_insn_ia64(PTR_TO_BFDVMA(mi), m_di_dis);
246 }
struct disassemble_info * m_di
Definition: IA64ISA.hpp:151
static void GNUbu_print_addr(bfd_vma di_vma, struct disassemble_info *di)
Definition: IA64ISA.cpp:100
bfd_vma VMA
Definition: ISATypes.hpp:79
virtual VMA getInsnTargetVMA(MachInsn *mi, VMA pc, ushort opIndex, ushort sz=0)
Definition: IA64ISA.cpp:202
virtual InsnDesc getInsnDesc(MachInsn *mi, ushort opIndex, ushort sz=0)
Definition: IA64ISA.cpp:143
#define PTR_TO_BFDVMA(x)
Definition: ISATypes.hpp:94
int GNUbu_fprintf(void *stream, const char *format,...)
Definition: ISA.cpp:173
virtual ushort getInsnNumOps(MachInsn *mi)
Definition: IA64ISA.cpp:225
int GNUbu_fprintf_stub(void *GCC_ATTR_UNUSED stream, const char *GCC_ATTR_UNUSED format,...)
Definition: ISA.cpp:191
DecodingCache * cacheLookup(MachInsn *cmi)
Definition: ISA.hpp:489
virtual void decode(std::ostream &os, MachInsn *mi, VMA vma, ushort opIndex)
Definition: IA64ISA.cpp:238
#define dis_return
Definition: gnu_dis-asm.h:79
unsigned short int ushort
Definition: uint.h:120
virtual ~IA64ISA()
Definition: IA64ISA.cpp:135
void set(IType t)
Definition: ISA.hpp:348
int GNUbu_read_memory(bfd_vma vma, bfd_byte *myaddr, unsigned int len, struct disassemble_info *GCC_ATTR_UNUSED di)
Definition: ISA.cpp:206
void cacheSet(MachInsn *cmi, ushort size)
Definition: ISA.hpp:501
MachInsn * insn_addr
Definition: ISA.hpp:516
static VMA GNUvma2vma(bfd_vma di_vma, MachInsn *GCC_ATTR_UNUSED insn_addr, VMA insn_vma)
Definition: IA64ISA.cpp:92
void GNUbu_print_addr_stub(bfd_vma GCC_ATTR_UNUSED di_vma, struct disassemble_info *GCC_ATTR_UNUSED di)
Definition: ISA.cpp:199
VMA insn_vma
Definition: ISA.hpp:517
IA64ISA()
Definition: IA64ISA.cpp:114
static MachInsn * ConvertMIToOpMI(MachInsn *mi, ushort opIndex)
Definition: IA64ISA.cpp:81
unsigned char MachInsnByte
Definition: ISATypes.hpp:88
void MachInsn
Definition: ISATypes.hpp:87
#define NULL
Definition: ElfHelper.cpp:85
GNUbu_disdata m_dis_data
Definition: IA64ISA.hpp:153
#define GCC_ATTR_UNUSED
Definition: gcc-attr.h:80
struct disassemble_info * m_di_dis
Definition: IA64ISA.hpp:152
static MachInsn * mi
Definition: x86ISAXed.cpp:91