Tracking commit: working in progress on dlopenDYNINSTlib()
[dyninst.git] / dyninstAPI / src / arch-ia64.h
1 /*
2  * Copyright (c) 1996 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * This license is for research uses.  For such uses, there is no
12  * charge. We define "research use" to mean you may freely use it
13  * inside your organization for whatever purposes you see fit. But you
14  * may not re-distribute Paradyn or parts of Paradyn, in any form
15  * source or binary (including derivatives), electronic or otherwise,
16  * to any other organization or entity without our permission.
17  * 
18  * (for other uses, please contact us at paradyn@cs.wisc.edu)
19  * 
20  * All warranties, including without limitation, any warranty of
21  * merchantability or fitness for a particular purpose, are hereby
22  * excluded.
23  * 
24  * By your use of Paradyn, you understand and agree that we (or any
25  * other person or entity with proprietary rights in Paradyn) are
26  * under no obligation to provide either maintenance services,
27  * update services, notices of latent defects, or correction of
28  * defects for Paradyn.
29  * 
30  * Even if advised of the possibility of such damages, under no
31  * circumstances shall we (or any other person or entity with
32  * proprietary rights in the software licensed hereunder) be liable
33  * to you or any third party for direct, indirect, or consequential
34  * damages of any character regardless of type of action, including,
35  * without limitation, loss of profits, loss of use, loss of good
36  * will, or computer failure or malfunction.  You agree to indemnify
37  * us (and any other person or entity with proprietary rights in the
38  * software licensed hereunder) for any and all liability it may
39  * incur to third parties resulting from your use of Paradyn.
40  */
41
42 // $Id: arch-ia64.h,v 1.3 2002/06/20 20:06:13 tlmiller Exp $
43 // ia64 instruction declarations
44
45 #if !defined(ia64_unknown_linux2_4)
46 #error "invalid architecture-os inclusion"
47 #endif
48
49 #ifndef _ARCH_IA64_H
50 #define _ARCH_IA64_H
51
52 #include "common/h/Types.h"
53 #include "inst-ia64.h"
54
55 /* So the IA-64 has these cute ideas about ILP, one consequence of which
56    is the design of its instruction set.  Instructions execute in parallel
57    until an architectural stop (certain instructions, types of bundles, etc)
58    is reached, which forces the processor to make it look like all the
59    instructions in the group since the the last stop were executed in
60    sequence.  The instructions are stored three to a bundle, which is 128
61    bits long, and includes three 41-bit instructions, as well as five bits
62    determining the 'template,' which includes architectural stop information,
63    as well as determining which execution unit(s) get which instruction(s).
64
65    The instructions themselves don't identify their execution unit, only
66    the major opcode of the instruction for that unit.  So considering an
67    instruction in isolation is an excercise in futility.
68
69    The question, then, is if we consider only whole bundles
70    'instructions' and do some magic in the instruction iterator,
71    of vice-versa...
72 */
73
74 class IA64_bundle;
75
76 class IA64_instruction {
77         friend class IA64_bundle;
78
79         public:
80                 IA64_instruction( uint64_t insn = 0, uint8_t templ = 0, IA64_bundle * mybl = 0 );
81
82                 /* Required of instructions; deprecate ASAP, since
83                    they don't have sensible semantics on the IA-64. */
84                 const void * ptr() const { return (void *)0; }
85                 uint32_t size() const { return 16; }
86
87                 uint64_t getMachineCode() { return instruction; }       
88
89         private:
90                 IA64_bundle * myBundle;
91
92                 uint64_t instruction;
93                 uint8_t templateID;
94         }; /* end the 41 bit instruction */
95
96 struct ia64_bundle_t {
97         uint64_t low;
98         uint64_t high;
99         };
100
101 class IA64_bundle {
102         public:
103                 IA64_bundle( uint64_t lowHalfBundle = 0, uint64_t highHalfBundle = 0 );
104                 IA64_bundle( uint8_t templateID, uint64_t instruction0, uint64_t instruction1, uint64_t instruction2 );
105                 IA64_bundle( uint8_t templateID, IA64_instruction & instruction0, IA64_instruction instruction1, IA64_instruction instruction2 );
106                 IA64_bundle( ia64_bundle_t rawBundle );
107                 IA64_bundle( uint8_t templateID, IA64_instruction & instruction0, IA64_instruction & instructionLX );
108
109                 ia64_bundle_t getMyBundle() const { return myBundle; }
110
111                 uint8_t getTemplateID() { return templateID; }
112                 IA64_instruction getInstruction0() { return instruction0; }
113                 IA64_instruction getInstruction1() { return instruction1; }
114                 IA64_instruction getInstruction2() { return instruction2; }
115                 IA64_instruction getInstruction( unsigned int slot );
116
117         private:
118                 IA64_instruction instruction0;
119                 IA64_instruction instruction1;
120                 IA64_instruction instruction2;
121                 uint8_t templateID;
122
123                 ia64_bundle_t myBundle;
124
125         }; /* end the 128 bit bundle */
126
127 typedef IA64_instruction instruction;
128
129 /* Required by symtab.h, which seems to use it to check
130    _instruction_ alignment.  OTOH, it doesn't seem to very
131    much paid attention to.  Anyway, IA-64 instruction bundles
132    are always 16-byte aligned. */
133 inline bool isAligned( const Address address ) {
134         return (address & 0xFFFFFFFFFFFFFFF0) == address;
135         } /* end isAligned() */
136
137 /* Required by linux.C to find the address bounds
138    of new dynamic heap segments. */
139 inline Address region_lo( const Address x ) {
140         #warning WAG
141         return 0x00000000;
142         } /* end region_lo */
143
144 /* Required by linux.C to find the address bounds
145    of new dynamic heap segments. */
146 inline Address region_hi( const Address x ) {
147         #warning WAG
148         return 0xf0000000;
149         } /* end region_hi */
150
151 /* Required by func-reloc.C to calculate relative displacements. */
152 int get_disp( instruction *insn );
153
154 /* Required by func-reloc.C to correct relative displacements after relocation. */
155 int set_disp( bool setDisp, instruction * insn, int newOffset, bool outOfFunc );
156
157 /* Convenience methods for func-reloc.C */
158 /* The problem being that neither of these really apply, do they? */
159 int sizeOfMachineInsn( instruction * insn );
160 int addressOfMachineInsn( instruction * insn );
161
162 /* Required by linux-ia64.C */
163 IA64_instruction generateAlteredAlloc( InsnAddr & allocAddr, int deltaLocal, int deltaOutput, int deltaRotate );
164 IA64_instruction generateShortConstantInRegister( unsigned int registerN, int imm22 );
165 IA64_instruction generateLongConstantInRegister( unsigned int registerN, long long int imm64 );
166 IA64_instruction generateLongBranchTo( long long int displacement64 );
167
168 #endif