709e0a610cb9dcebdb2d8491afa717cbd13405c0
[gem5.git] / src / arch / x86 / insts / static_inst.cc
1 /*
2 * Copyright (c) 2007 The Hewlett-Packard Development Company
3 * Copyright (c) 2013 Advanced Micro Devices, Inc.
4 * All rights reserved.
5 *
6 * The license below extends only to copyright in the software and shall
7 * not be construed as granting a license to any other intellectual
8 * property including but not limited to intellectual property relating
9 * to a hardware implementation of the functionality of the software
10 * licensed hereunder. You may use the software subject to the license
11 * terms below provided that you ensure that this notice is replicated
12 * unmodified and in its entirety in all distributions of the software,
13 * modified or unmodified, in source code or in binary form.
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions are
17 * met: redistributions of source code must retain the above copyright
18 * notice, this list of conditions and the following disclaimer;
19 * redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the distribution;
22 * neither the name of the copyright holders nor the names of its
23 * contributors may be used to endorse or promote products derived from
24 * this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 *
38 * Authors: Gabe Black
39 */
40
41 #include "arch/x86/insts/static_inst.hh"
42 #include "arch/x86/regs/segment.hh"
43 #include "cpu/reg_class.hh"
44
45 namespace X86ISA
46 {
47 void X86StaticInst::printMnemonic(std::ostream &os,
48 const char * mnemonic) const
49 {
50 ccprintf(os, " %s ", mnemonic);
51 }
52
53 void X86StaticInst::printMnemonic(std::ostream &os,
54 const char * instMnemonic, const char * mnemonic) const
55 {
56 ccprintf(os, " %s : %s ", instMnemonic, mnemonic);
57 }
58
59 void X86StaticInst::printSegment(std::ostream &os, int segment) const
60 {
61 switch (segment)
62 {
63 case SEGMENT_REG_ES:
64 ccprintf(os, "ES");
65 break;
66 case SEGMENT_REG_CS:
67 ccprintf(os, "CS");
68 break;
69 case SEGMENT_REG_SS:
70 ccprintf(os, "SS");
71 break;
72 case SEGMENT_REG_DS:
73 ccprintf(os, "DS");
74 break;
75 case SEGMENT_REG_FS:
76 ccprintf(os, "FS");
77 break;
78 case SEGMENT_REG_GS:
79 ccprintf(os, "GS");
80 break;
81 case SEGMENT_REG_HS:
82 ccprintf(os, "HS");
83 break;
84 case SEGMENT_REG_TSL:
85 ccprintf(os, "TSL");
86 break;
87 case SEGMENT_REG_TSG:
88 ccprintf(os, "TSG");
89 break;
90 case SEGMENT_REG_LS:
91 ccprintf(os, "LS");
92 break;
93 case SEGMENT_REG_MS:
94 ccprintf(os, "MS");
95 break;
96 case SYS_SEGMENT_REG_TR:
97 ccprintf(os, "TR");
98 break;
99 case SYS_SEGMENT_REG_IDTR:
100 ccprintf(os, "IDTR");
101 break;
102 default:
103 panic("Unrecognized segment %d\n", segment);
104 }
105 }
106
107 void
108 X86StaticInst::printSrcReg(std::ostream &os, int reg, int size) const
109 {
110 if (_numSrcRegs > reg)
111 printReg(os, _srcRegIdx[reg], size);
112 }
113
114 void
115 X86StaticInst::printDestReg(std::ostream &os, int reg, int size) const
116 {
117 if (_numDestRegs > reg)
118 printReg(os, _destRegIdx[reg], size);
119 }
120
121 void
122 X86StaticInst::printReg(std::ostream &os, int reg, int size) const
123 {
124 assert(size == 1 || size == 2 || size == 4 || size == 8);
125 static const char * abcdFormats[9] =
126 {"", "%s", "%sx", "", "e%sx", "", "", "", "r%sx"};
127 static const char * piFormats[9] =
128 {"", "%s", "%s", "", "e%s", "", "", "", "r%s"};
129 static const char * longFormats[9] =
130 {"", "r%sb", "r%sw", "", "r%sd", "", "", "", "r%s"};
131 static const char * microFormats[9] =
132 {"", "t%db", "t%dw", "", "t%dd", "", "", "", "t%d"};
133
134 RegIndex rel_reg;
135
136 switch (regIdxToClass(reg, &rel_reg)) {
137 case IntRegClass: {
138 const char * suffix = "";
139 bool fold = rel_reg & IntFoldBit;
140 rel_reg &= ~IntFoldBit;
141
142 if (fold)
143 suffix = "h";
144 else if (rel_reg < 8 && size == 1)
145 suffix = "l";
146
147 switch (rel_reg) {
148 case INTREG_RAX:
149 ccprintf(os, abcdFormats[size], "a");
150 break;
151 case INTREG_RBX:
152 ccprintf(os, abcdFormats[size], "b");
153 break;
154 case INTREG_RCX:
155 ccprintf(os, abcdFormats[size], "c");
156 break;
157 case INTREG_RDX:
158 ccprintf(os, abcdFormats[size], "d");
159 break;
160 case INTREG_RSP:
161 ccprintf(os, piFormats[size], "sp");
162 break;
163 case INTREG_RBP:
164 ccprintf(os, piFormats[size], "bp");
165 break;
166 case INTREG_RSI:
167 ccprintf(os, piFormats[size], "si");
168 break;
169 case INTREG_RDI:
170 ccprintf(os, piFormats[size], "di");
171 break;
172 case INTREG_R8W:
173 ccprintf(os, longFormats[size], "8");
174 break;
175 case INTREG_R9W:
176 ccprintf(os, longFormats[size], "9");
177 break;
178 case INTREG_R10W:
179 ccprintf(os, longFormats[size], "10");
180 break;
181 case INTREG_R11W:
182 ccprintf(os, longFormats[size], "11");
183 break;
184 case INTREG_R12W:
185 ccprintf(os, longFormats[size], "12");
186 break;
187 case INTREG_R13W:
188 ccprintf(os, longFormats[size], "13");
189 break;
190 case INTREG_R14W:
191 ccprintf(os, longFormats[size], "14");
192 break;
193 case INTREG_R15W:
194 ccprintf(os, longFormats[size], "15");
195 break;
196 default:
197 ccprintf(os, microFormats[size], rel_reg - NUM_INTREGS);
198 }
199 ccprintf(os, suffix);
200 break;
201 }
202
203 case FloatRegClass: {
204 if (rel_reg < NumMMXRegs) {
205 ccprintf(os, "%%mmx%d", rel_reg);
206 return;
207 }
208 rel_reg -= NumMMXRegs;
209 if (rel_reg < NumXMMRegs * 2) {
210 ccprintf(os, "%%xmm%d_%s", rel_reg / 2,
211 (rel_reg % 2) ? "high": "low");
212 return;
213 }
214 rel_reg -= NumXMMRegs * 2;
215 if (rel_reg < NumMicroFpRegs) {
216 ccprintf(os, "%%ufp%d", rel_reg);
217 return;
218 }
219 rel_reg -= NumMicroFpRegs;
220 ccprintf(os, "%%st(%d)", rel_reg);
221 break;
222 }
223
224 case CCRegClass:
225 ccprintf(os, "%%cc%d", rel_reg);
226 break;
227
228 case MiscRegClass:
229 switch (rel_reg) {
230 default:
231 ccprintf(os, "%%ctrl%d", rel_reg);
232 }
233 break;
234 }
235 }
236
237 void X86StaticInst::printMem(std::ostream &os, uint8_t segment,
238 uint8_t scale, RegIndex index, RegIndex base,
239 uint64_t disp, uint8_t addressSize, bool rip) const
240 {
241 bool someAddr = false;
242 printSegment(os, segment);
243 os << ":[";
244 if (rip) {
245 os << "rip";
246 someAddr = true;
247 } else {
248 if (scale != 0 && index != ZeroReg)
249 {
250 if (scale != 1)
251 ccprintf(os, "%d*", scale);
252 printReg(os, index, addressSize);
253 someAddr = true;
254 }
255 if (base != ZeroReg)
256 {
257 if (someAddr)
258 os << " + ";
259 printReg(os, base, addressSize);
260 someAddr = true;
261 }
262 }
263 if (disp != 0)
264 {
265 if (someAddr)
266 os << " + ";
267 ccprintf(os, "%#x", disp);
268 someAddr = true;
269 }
270 if (!someAddr)
271 os << "0";
272 os << "]";
273 }
274
275 std::string X86StaticInst::generateDisassembly(Addr pc,
276 const SymbolTable *symtab) const
277 {
278 std::stringstream ss;
279
280 printMnemonic(ss, mnemonic);
281
282 return ss.str();
283 }
284 }