OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 // | 4 // |
5 // Modified by the Subzero authors. | 5 // Modified by the Subzero authors. |
6 // | 6 // |
7 //===- subzero/src/assembler_ia32.cpp - Assembler for x86-32 -------------===// | 7 //===- subzero/src/assembler_ia32.cpp - Assembler for x86-32 -------------===// |
8 // | 8 // |
9 // The Subzero Code Generator | 9 // The Subzero Code Generator |
10 // | 10 // |
11 // This file is distributed under the University of Illinois Open Source | 11 // This file is distributed under the University of Illinois Open Source |
12 // License. See LICENSE.TXT for details. | 12 // License. See LICENSE.TXT for details. |
13 // | 13 // |
14 //===----------------------------------------------------------------------===// | 14 //===----------------------------------------------------------------------===// |
15 // | 15 // |
16 // This file implements the Assembler class for x86-32. | 16 // This file implements the Assembler class for x86-32. |
17 // | 17 // |
18 //===----------------------------------------------------------------------===// | 18 //===----------------------------------------------------------------------===// |
19 | 19 |
20 #include "assembler_ia32.h" | 20 #include "assembler_ia32.h" |
21 #include "IceCfg.h" | 21 #include "IceCfg.h" |
22 #include "IceMemoryRegion.h" | 22 #include "IceMemoryRegion.h" |
23 #include "IceOperand.h" | 23 #include "IceOperand.h" |
24 | 24 |
25 namespace Ice { | 25 namespace Ice { |
26 namespace x86 { | 26 namespace x86 { |
27 | 27 |
| 28 const Type BrokenType = IceType_i32; |
| 29 |
28 class DirectCallRelocation : public AssemblerFixup { | 30 class DirectCallRelocation : public AssemblerFixup { |
29 public: | 31 public: |
30 static DirectCallRelocation *create(Assembler *Asm, FixupKind Kind, | 32 static DirectCallRelocation *create(Assembler *Asm, FixupKind Kind, |
31 const ConstantRelocatable *Sym) { | 33 const ConstantRelocatable *Sym) { |
32 return new (Asm->Allocate<DirectCallRelocation>()) | 34 return new (Asm->Allocate<DirectCallRelocation>()) |
33 DirectCallRelocation(Kind, Sym); | 35 DirectCallRelocation(Kind, Sym); |
34 } | 36 } |
35 | 37 |
36 void Process(const MemoryRegion ®ion, intptr_t position) { | 38 void Process(const MemoryRegion ®ion, intptr_t position) { |
37 // Direct calls are relative to the following instruction on x86. | 39 // Direct calls are relative to the following instruction on x86. |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 | 100 |
99 void AssemblerX86::pushl(const Address &address) { | 101 void AssemblerX86::pushl(const Address &address) { |
100 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 102 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
101 EmitUint8(0xFF); | 103 EmitUint8(0xFF); |
102 EmitOperand(6, address); | 104 EmitOperand(6, address); |
103 } | 105 } |
104 | 106 |
105 void AssemblerX86::pushl(const Immediate &imm) { | 107 void AssemblerX86::pushl(const Immediate &imm) { |
106 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 108 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
107 EmitUint8(0x68); | 109 EmitUint8(0x68); |
108 EmitImmediate(imm); | 110 EmitImmediate(BrokenType, imm); |
109 } | 111 } |
110 | 112 |
111 void AssemblerX86::popl(GPRRegister reg) { | 113 void AssemblerX86::popl(GPRRegister reg) { |
112 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 114 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
113 EmitUint8(0x58 + reg); | 115 EmitUint8(0x58 + reg); |
114 } | 116 } |
115 | 117 |
116 void AssemblerX86::popl(const Address &address) { | 118 void AssemblerX86::popl(const Address &address) { |
117 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 119 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
118 EmitUint8(0x8F); | 120 EmitUint8(0x8F); |
(...skipping 13 matching lines...) Expand all Loading... |
132 void AssemblerX86::setcc(CondX86::BrCond condition, ByteRegister dst) { | 134 void AssemblerX86::setcc(CondX86::BrCond condition, ByteRegister dst) { |
133 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 135 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
134 EmitUint8(0x0F); | 136 EmitUint8(0x0F); |
135 EmitUint8(0x90 + condition); | 137 EmitUint8(0x90 + condition); |
136 EmitUint8(0xC0 + dst); | 138 EmitUint8(0xC0 + dst); |
137 } | 139 } |
138 | 140 |
139 void AssemblerX86::movl(GPRRegister dst, const Immediate &imm) { | 141 void AssemblerX86::movl(GPRRegister dst, const Immediate &imm) { |
140 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 142 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
141 EmitUint8(0xB8 + dst); | 143 EmitUint8(0xB8 + dst); |
142 EmitImmediate(imm); | 144 EmitImmediate(BrokenType, imm); |
143 } | 145 } |
144 | 146 |
145 void AssemblerX86::movl(GPRRegister dst, GPRRegister src) { | 147 void AssemblerX86::movl(GPRRegister dst, GPRRegister src) { |
146 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 148 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
147 EmitUint8(0x89); | 149 EmitUint8(0x89); |
148 EmitRegisterOperand(src, dst); | 150 EmitRegisterOperand(src, dst); |
149 } | 151 } |
150 | 152 |
151 void AssemblerX86::movl(GPRRegister dst, const Address &src) { | 153 void AssemblerX86::movl(GPRRegister dst, const Address &src) { |
152 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 154 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
153 EmitUint8(0x8B); | 155 EmitUint8(0x8B); |
154 EmitOperand(dst, src); | 156 EmitOperand(dst, src); |
155 } | 157 } |
156 | 158 |
157 void AssemblerX86::movl(const Address &dst, GPRRegister src) { | 159 void AssemblerX86::movl(const Address &dst, GPRRegister src) { |
158 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 160 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
159 EmitUint8(0x89); | 161 EmitUint8(0x89); |
160 EmitOperand(src, dst); | 162 EmitOperand(src, dst); |
161 } | 163 } |
162 | 164 |
163 void AssemblerX86::movl(const Address &dst, const Immediate &imm) { | 165 void AssemblerX86::movl(const Address &dst, const Immediate &imm) { |
164 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 166 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
165 EmitUint8(0xC7); | 167 EmitUint8(0xC7); |
166 EmitOperand(0, dst); | 168 EmitOperand(0, dst); |
167 EmitImmediate(imm); | 169 EmitImmediate(BrokenType, imm); |
168 } | 170 } |
169 | 171 |
170 void AssemblerX86::movzxb(GPRRegister dst, ByteRegister src) { | 172 void AssemblerX86::movzxb(GPRRegister dst, ByteRegister src) { |
171 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 173 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
172 EmitUint8(0x0F); | 174 EmitUint8(0x0F); |
173 EmitUint8(0xB6); | 175 EmitUint8(0xB6); |
174 EmitRegisterOperand(dst, src); | 176 EmitRegisterOperand(dst, src); |
175 } | 177 } |
176 | 178 |
177 void AssemblerX86::movzxb(GPRRegister dst, const Address &src) { | 179 void AssemblerX86::movzxb(GPRRegister dst, const Address &src) { |
(...skipping 946 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1124 } | 1126 } |
1125 | 1127 |
1126 void AssemblerX86::fincstp() { | 1128 void AssemblerX86::fincstp() { |
1127 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1129 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1128 EmitUint8(0xD9); | 1130 EmitUint8(0xD9); |
1129 EmitUint8(0xF7); | 1131 EmitUint8(0xF7); |
1130 } | 1132 } |
1131 | 1133 |
1132 void AssemblerX86::cmpl(GPRRegister reg, const Immediate &imm) { | 1134 void AssemblerX86::cmpl(GPRRegister reg, const Immediate &imm) { |
1133 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1135 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1134 EmitComplex(7, Operand(reg), imm); | 1136 EmitComplex(BrokenType, 7, Operand(reg), imm); |
1135 } | 1137 } |
1136 | 1138 |
1137 void AssemblerX86::cmpl(GPRRegister reg0, GPRRegister reg1) { | 1139 void AssemblerX86::cmpl(GPRRegister reg0, GPRRegister reg1) { |
1138 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1140 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1139 EmitUint8(0x3B); | 1141 EmitUint8(0x3B); |
1140 EmitOperand(reg0, Operand(reg1)); | 1142 EmitOperand(reg0, Operand(reg1)); |
1141 } | 1143 } |
1142 | 1144 |
1143 void AssemblerX86::cmpl(GPRRegister reg, const Address &address) { | 1145 void AssemblerX86::cmpl(GPRRegister reg, const Address &address) { |
1144 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1146 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1145 EmitUint8(0x3B); | 1147 EmitUint8(0x3B); |
1146 EmitOperand(reg, address); | 1148 EmitOperand(reg, address); |
1147 } | 1149 } |
1148 | 1150 |
1149 void AssemblerX86::cmpl(const Address &address, GPRRegister reg) { | 1151 void AssemblerX86::cmpl(const Address &address, GPRRegister reg) { |
1150 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1152 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1151 EmitUint8(0x39); | 1153 EmitUint8(0x39); |
1152 EmitOperand(reg, address); | 1154 EmitOperand(reg, address); |
1153 } | 1155 } |
1154 | 1156 |
1155 void AssemblerX86::cmpl(const Address &address, const Immediate &imm) { | 1157 void AssemblerX86::cmpl(const Address &address, const Immediate &imm) { |
1156 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1158 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1157 EmitComplex(7, address, imm); | 1159 EmitComplex(BrokenType, 7, address, imm); |
1158 } | 1160 } |
1159 | 1161 |
1160 void AssemblerX86::cmpb(const Address &address, const Immediate &imm) { | 1162 void AssemblerX86::cmpb(const Address &address, const Immediate &imm) { |
1161 assert(imm.is_int8()); | 1163 assert(imm.is_int8()); |
1162 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1164 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1163 EmitUint8(0x80); | 1165 EmitUint8(0x80); |
1164 EmitOperand(7, address); | 1166 EmitOperand(7, address); |
1165 EmitUint8(imm.value() & 0xFF); | 1167 EmitUint8(imm.value() & 0xFF); |
1166 } | 1168 } |
1167 | 1169 |
(...skipping 12 matching lines...) Expand all Loading... |
1180 if (reg == RegX8632::Encoded_Reg_eax) { | 1182 if (reg == RegX8632::Encoded_Reg_eax) { |
1181 EmitUint8(0xA8); | 1183 EmitUint8(0xA8); |
1182 } else { | 1184 } else { |
1183 EmitUint8(0xF6); | 1185 EmitUint8(0xF6); |
1184 EmitUint8(0xC0 + reg); | 1186 EmitUint8(0xC0 + reg); |
1185 } | 1187 } |
1186 EmitUint8(immediate.value() & 0xFF); | 1188 EmitUint8(immediate.value() & 0xFF); |
1187 } else if (reg == RegX8632::Encoded_Reg_eax) { | 1189 } else if (reg == RegX8632::Encoded_Reg_eax) { |
1188 // Use short form if the destination is EAX. | 1190 // Use short form if the destination is EAX. |
1189 EmitUint8(0xA9); | 1191 EmitUint8(0xA9); |
1190 EmitImmediate(immediate); | 1192 EmitImmediate(BrokenType, immediate); |
1191 } else { | 1193 } else { |
1192 EmitUint8(0xF7); | 1194 EmitUint8(0xF7); |
1193 EmitOperand(0, Operand(reg)); | 1195 EmitOperand(0, Operand(reg)); |
1194 EmitImmediate(immediate); | 1196 EmitImmediate(BrokenType, immediate); |
1195 } | 1197 } |
1196 } | 1198 } |
1197 | 1199 |
1198 void AssemblerX86::And(Type Ty, GPRRegister dst, GPRRegister src) { | 1200 void AssemblerX86::And(Type Ty, GPRRegister dst, GPRRegister src) { |
1199 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1201 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1200 if (Ty == IceType_i16) | 1202 if (Ty == IceType_i16) |
1201 EmitOperandSizeOverride(); | 1203 EmitOperandSizeOverride(); |
1202 if (Ty == IceType_i8 || Ty == IceType_i1) | 1204 if (Ty == IceType_i8 || Ty == IceType_i1) |
1203 EmitUint8(0x22); | 1205 EmitUint8(0x22); |
1204 else | 1206 else |
(...skipping 13 matching lines...) Expand all Loading... |
1218 } | 1220 } |
1219 | 1221 |
1220 void AssemblerX86::And(Type Ty, GPRRegister dst, const Immediate &imm) { | 1222 void AssemblerX86::And(Type Ty, GPRRegister dst, const Immediate &imm) { |
1221 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1223 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1222 if (Ty == IceType_i8 || Ty == IceType_i1) { | 1224 if (Ty == IceType_i8 || Ty == IceType_i1) { |
1223 EmitComplexI8(4, Operand(dst), imm); | 1225 EmitComplexI8(4, Operand(dst), imm); |
1224 return; | 1226 return; |
1225 } | 1227 } |
1226 if (Ty == IceType_i16) | 1228 if (Ty == IceType_i16) |
1227 EmitOperandSizeOverride(); | 1229 EmitOperandSizeOverride(); |
1228 EmitComplex(4, Operand(dst), imm); | 1230 EmitComplex(Ty, 4, Operand(dst), imm); |
1229 } | 1231 } |
1230 | 1232 |
1231 void AssemblerX86::Or(Type Ty, GPRRegister dst, GPRRegister src) { | 1233 void AssemblerX86::Or(Type Ty, GPRRegister dst, GPRRegister src) { |
1232 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1234 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1233 if (Ty == IceType_i16) | 1235 if (Ty == IceType_i16) |
1234 EmitOperandSizeOverride(); | 1236 EmitOperandSizeOverride(); |
1235 if (Ty == IceType_i8 || Ty == IceType_i1) | 1237 if (Ty == IceType_i8 || Ty == IceType_i1) |
1236 EmitUint8(0x0A); | 1238 EmitUint8(0x0A); |
1237 else | 1239 else |
1238 EmitUint8(0x0B); | 1240 EmitUint8(0x0B); |
(...skipping 12 matching lines...) Expand all Loading... |
1251 } | 1253 } |
1252 | 1254 |
1253 void AssemblerX86::Or(Type Ty, GPRRegister dst, const Immediate &imm) { | 1255 void AssemblerX86::Or(Type Ty, GPRRegister dst, const Immediate &imm) { |
1254 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1256 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1255 if (Ty == IceType_i8 || Ty == IceType_i1) { | 1257 if (Ty == IceType_i8 || Ty == IceType_i1) { |
1256 EmitComplexI8(1, Operand(dst), imm); | 1258 EmitComplexI8(1, Operand(dst), imm); |
1257 return; | 1259 return; |
1258 } | 1260 } |
1259 if (Ty == IceType_i16) | 1261 if (Ty == IceType_i16) |
1260 EmitOperandSizeOverride(); | 1262 EmitOperandSizeOverride(); |
1261 EmitComplex(1, Operand(dst), imm); | 1263 EmitComplex(Ty, 1, Operand(dst), imm); |
1262 } | 1264 } |
1263 | 1265 |
1264 void AssemblerX86::Xor(Type Ty, GPRRegister dst, GPRRegister src) { | 1266 void AssemblerX86::Xor(Type Ty, GPRRegister dst, GPRRegister src) { |
1265 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1267 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1266 if (Ty == IceType_i16) | 1268 if (Ty == IceType_i16) |
1267 EmitOperandSizeOverride(); | 1269 EmitOperandSizeOverride(); |
1268 if (Ty == IceType_i8 || Ty == IceType_i1) | 1270 if (Ty == IceType_i8 || Ty == IceType_i1) |
1269 EmitUint8(0x32); | 1271 EmitUint8(0x32); |
1270 else | 1272 else |
1271 EmitUint8(0x33); | 1273 EmitUint8(0x33); |
(...skipping 12 matching lines...) Expand all Loading... |
1284 } | 1286 } |
1285 | 1287 |
1286 void AssemblerX86::Xor(Type Ty, GPRRegister dst, const Immediate &imm) { | 1288 void AssemblerX86::Xor(Type Ty, GPRRegister dst, const Immediate &imm) { |
1287 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1289 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1288 if (Ty == IceType_i8 || Ty == IceType_i1) { | 1290 if (Ty == IceType_i8 || Ty == IceType_i1) { |
1289 EmitComplexI8(6, Operand(dst), imm); | 1291 EmitComplexI8(6, Operand(dst), imm); |
1290 return; | 1292 return; |
1291 } | 1293 } |
1292 if (Ty == IceType_i16) | 1294 if (Ty == IceType_i16) |
1293 EmitOperandSizeOverride(); | 1295 EmitOperandSizeOverride(); |
1294 EmitComplex(6, Operand(dst), imm); | 1296 EmitComplex(Ty, 6, Operand(dst), imm); |
1295 } | 1297 } |
1296 | 1298 |
1297 void AssemblerX86::add(Type Ty, GPRRegister dst, GPRRegister src) { | 1299 void AssemblerX86::add(Type Ty, GPRRegister dst, GPRRegister src) { |
1298 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1300 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1299 if (Ty == IceType_i16) | 1301 if (Ty == IceType_i16) |
1300 EmitOperandSizeOverride(); | 1302 EmitOperandSizeOverride(); |
1301 if (Ty == IceType_i8 || Ty == IceType_i1) | 1303 if (Ty == IceType_i8 || Ty == IceType_i1) |
1302 EmitUint8(0x02); | 1304 EmitUint8(0x02); |
1303 else | 1305 else |
1304 EmitUint8(0x03); | 1306 EmitUint8(0x03); |
(...skipping 12 matching lines...) Expand all Loading... |
1317 } | 1319 } |
1318 | 1320 |
1319 void AssemblerX86::add(Type Ty, GPRRegister reg, const Immediate &imm) { | 1321 void AssemblerX86::add(Type Ty, GPRRegister reg, const Immediate &imm) { |
1320 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1322 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1321 if (Ty == IceType_i8 || Ty == IceType_i1) { | 1323 if (Ty == IceType_i8 || Ty == IceType_i1) { |
1322 EmitComplexI8(0, Operand(reg), imm); | 1324 EmitComplexI8(0, Operand(reg), imm); |
1323 return; | 1325 return; |
1324 } | 1326 } |
1325 if (Ty == IceType_i16) | 1327 if (Ty == IceType_i16) |
1326 EmitOperandSizeOverride(); | 1328 EmitOperandSizeOverride(); |
1327 EmitComplex(0, Operand(reg), imm); | 1329 EmitComplex(Ty, 0, Operand(reg), imm); |
1328 } | 1330 } |
1329 | 1331 |
1330 void AssemblerX86::adc(Type Ty, GPRRegister dst, GPRRegister src) { | 1332 void AssemblerX86::adc(Type Ty, GPRRegister dst, GPRRegister src) { |
1331 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1333 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1332 if (Ty == IceType_i16) | 1334 if (Ty == IceType_i16) |
1333 EmitOperandSizeOverride(); | 1335 EmitOperandSizeOverride(); |
1334 if (Ty == IceType_i8 || Ty == IceType_i1) | 1336 if (Ty == IceType_i8 || Ty == IceType_i1) |
1335 EmitUint8(0x12); | 1337 EmitUint8(0x12); |
1336 else | 1338 else |
1337 EmitUint8(0x13); | 1339 EmitUint8(0x13); |
(...skipping 12 matching lines...) Expand all Loading... |
1350 } | 1352 } |
1351 | 1353 |
1352 void AssemblerX86::adc(Type Ty, GPRRegister reg, const Immediate &imm) { | 1354 void AssemblerX86::adc(Type Ty, GPRRegister reg, const Immediate &imm) { |
1353 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1355 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1354 if (Ty == IceType_i8 || Ty == IceType_i1) { | 1356 if (Ty == IceType_i8 || Ty == IceType_i1) { |
1355 EmitComplexI8(2, Operand(reg), imm); | 1357 EmitComplexI8(2, Operand(reg), imm); |
1356 return; | 1358 return; |
1357 } | 1359 } |
1358 if (Ty == IceType_i16) | 1360 if (Ty == IceType_i16) |
1359 EmitOperandSizeOverride(); | 1361 EmitOperandSizeOverride(); |
1360 EmitComplex(2, Operand(reg), imm); | 1362 EmitComplex(Ty, 2, Operand(reg), imm); |
1361 } | 1363 } |
1362 | 1364 |
1363 void AssemblerX86::sub(Type Ty, GPRRegister dst, GPRRegister src) { | 1365 void AssemblerX86::sub(Type Ty, GPRRegister dst, GPRRegister src) { |
1364 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1366 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1365 if (Ty == IceType_i16) | 1367 if (Ty == IceType_i16) |
1366 EmitOperandSizeOverride(); | 1368 EmitOperandSizeOverride(); |
1367 if (Ty == IceType_i8 || Ty == IceType_i1) | 1369 if (Ty == IceType_i8 || Ty == IceType_i1) |
1368 EmitUint8(0x2A); | 1370 EmitUint8(0x2A); |
1369 else | 1371 else |
1370 EmitUint8(0x2B); | 1372 EmitUint8(0x2B); |
(...skipping 12 matching lines...) Expand all Loading... |
1383 } | 1385 } |
1384 | 1386 |
1385 void AssemblerX86::sub(Type Ty, GPRRegister reg, const Immediate &imm) { | 1387 void AssemblerX86::sub(Type Ty, GPRRegister reg, const Immediate &imm) { |
1386 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1388 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1387 if (Ty == IceType_i8 || Ty == IceType_i1) { | 1389 if (Ty == IceType_i8 || Ty == IceType_i1) { |
1388 EmitComplexI8(5, Operand(reg), imm); | 1390 EmitComplexI8(5, Operand(reg), imm); |
1389 return; | 1391 return; |
1390 } | 1392 } |
1391 if (Ty == IceType_i16) | 1393 if (Ty == IceType_i16) |
1392 EmitOperandSizeOverride(); | 1394 EmitOperandSizeOverride(); |
1393 EmitComplex(5, Operand(reg), imm); | 1395 EmitComplex(Ty, 5, Operand(reg), imm); |
1394 } | 1396 } |
1395 | 1397 |
1396 void AssemblerX86::sbb(Type Ty, GPRRegister dst, GPRRegister src) { | 1398 void AssemblerX86::sbb(Type Ty, GPRRegister dst, GPRRegister src) { |
1397 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1399 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1398 if (Ty == IceType_i16) | 1400 if (Ty == IceType_i16) |
1399 EmitOperandSizeOverride(); | 1401 EmitOperandSizeOverride(); |
1400 if (Ty == IceType_i8 || Ty == IceType_i1) | 1402 if (Ty == IceType_i8 || Ty == IceType_i1) |
1401 EmitUint8(0x1A); | 1403 EmitUint8(0x1A); |
1402 else | 1404 else |
1403 EmitUint8(0x1B); | 1405 EmitUint8(0x1B); |
(...skipping 12 matching lines...) Expand all Loading... |
1416 } | 1418 } |
1417 | 1419 |
1418 void AssemblerX86::sbb(Type Ty, GPRRegister reg, const Immediate &imm) { | 1420 void AssemblerX86::sbb(Type Ty, GPRRegister reg, const Immediate &imm) { |
1419 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1421 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1420 if (Ty == IceType_i8 || Ty == IceType_i1) { | 1422 if (Ty == IceType_i8 || Ty == IceType_i1) { |
1421 EmitComplexI8(3, Operand(reg), imm); | 1423 EmitComplexI8(3, Operand(reg), imm); |
1422 return; | 1424 return; |
1423 } | 1425 } |
1424 if (Ty == IceType_i16) | 1426 if (Ty == IceType_i16) |
1425 EmitOperandSizeOverride(); | 1427 EmitOperandSizeOverride(); |
1426 EmitComplex(3, Operand(reg), imm); | 1428 EmitComplex(Ty, 3, Operand(reg), imm); |
1427 } | 1429 } |
1428 | 1430 |
1429 void AssemblerX86::cbw() { | 1431 void AssemblerX86::cbw() { |
1430 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1432 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1431 EmitOperandSizeOverride(); | 1433 EmitOperandSizeOverride(); |
1432 EmitUint8(0x98); | 1434 EmitUint8(0x98); |
1433 } | 1435 } |
1434 | 1436 |
1435 void AssemblerX86::cwd() { | 1437 void AssemblerX86::cwd() { |
1436 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1438 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1491 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1493 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1492 EmitUint8(0x0F); | 1494 EmitUint8(0x0F); |
1493 EmitUint8(0xAF); | 1495 EmitUint8(0xAF); |
1494 EmitOperand(dst, Operand(src)); | 1496 EmitOperand(dst, Operand(src)); |
1495 } | 1497 } |
1496 | 1498 |
1497 void AssemblerX86::imull(GPRRegister reg, const Immediate &imm) { | 1499 void AssemblerX86::imull(GPRRegister reg, const Immediate &imm) { |
1498 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1500 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1499 EmitUint8(0x69); | 1501 EmitUint8(0x69); |
1500 EmitOperand(reg, Operand(reg)); | 1502 EmitOperand(reg, Operand(reg)); |
1501 EmitImmediate(imm); | 1503 EmitImmediate(BrokenType, imm); |
1502 } | 1504 } |
1503 | 1505 |
1504 void AssemblerX86::imull(GPRRegister reg, const Address &address) { | 1506 void AssemblerX86::imull(GPRRegister reg, const Address &address) { |
1505 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1507 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1506 EmitUint8(0x0F); | 1508 EmitUint8(0x0F); |
1507 EmitUint8(0xAF); | 1509 EmitUint8(0xAF); |
1508 EmitOperand(reg, address); | 1510 EmitOperand(reg, address); |
1509 } | 1511 } |
1510 | 1512 |
1511 void AssemblerX86::imull(GPRRegister reg) { | 1513 void AssemblerX86::imull(GPRRegister reg) { |
(...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1980 EmitUint8(operand.encoding_[0] + (rm << 3)); | 1982 EmitUint8(operand.encoding_[0] + (rm << 3)); |
1981 if (operand.fixup()) { | 1983 if (operand.fixup()) { |
1982 EmitFixup(operand.fixup()); | 1984 EmitFixup(operand.fixup()); |
1983 } | 1985 } |
1984 // Emit the rest of the encoded operand. | 1986 // Emit the rest of the encoded operand. |
1985 for (intptr_t i = 1; i < length; i++) { | 1987 for (intptr_t i = 1; i < length; i++) { |
1986 EmitUint8(operand.encoding_[i]); | 1988 EmitUint8(operand.encoding_[i]); |
1987 } | 1989 } |
1988 } | 1990 } |
1989 | 1991 |
1990 void AssemblerX86::EmitImmediate(const Immediate &imm) { | 1992 void AssemblerX86::EmitImmediate(Type Ty, const Immediate &imm) { |
1991 EmitInt32(imm.value()); | 1993 if (Ty == IceType_i16) |
| 1994 EmitInt16(imm.value()); |
| 1995 else |
| 1996 EmitInt32(imm.value()); |
1992 } | 1997 } |
1993 | 1998 |
1994 void AssemblerX86::EmitComplexI8(int rm, const Operand &operand, | 1999 void AssemblerX86::EmitComplexI8(int rm, const Operand &operand, |
1995 const Immediate &immediate) { | 2000 const Immediate &immediate) { |
1996 assert(rm >= 0 && rm < 8); | 2001 assert(rm >= 0 && rm < 8); |
1997 assert(immediate.is_int8()); | 2002 assert(immediate.is_int8()); |
1998 if (operand.IsRegister(RegX8632::Encoded_Reg_eax)) { | 2003 if (operand.IsRegister(RegX8632::Encoded_Reg_eax)) { |
1999 // Use short form if the destination is al. | 2004 // Use short form if the destination is al. |
2000 EmitUint8(0x04 + (rm << 3)); | 2005 EmitUint8(0x04 + (rm << 3)); |
2001 EmitUint8(immediate.value() & 0xFF); | 2006 EmitUint8(immediate.value() & 0xFF); |
2002 } else { | 2007 } else { |
2003 // Use sign-extended 8-bit immediate. | 2008 // Use sign-extended 8-bit immediate. |
2004 EmitUint8(0x80); | 2009 EmitUint8(0x80); |
2005 EmitOperand(rm, operand); | 2010 EmitOperand(rm, operand); |
2006 EmitUint8(immediate.value() & 0xFF); | 2011 EmitUint8(immediate.value() & 0xFF); |
2007 } | 2012 } |
2008 } | 2013 } |
2009 | 2014 |
2010 void AssemblerX86::EmitComplex(int rm, const Operand &operand, | 2015 void AssemblerX86::EmitComplex(Type Ty, int rm, const Operand &operand, |
2011 const Immediate &immediate) { | 2016 const Immediate &immediate) { |
2012 assert(rm >= 0 && rm < 8); | 2017 assert(rm >= 0 && rm < 8); |
2013 if (immediate.is_int8()) { | 2018 if (immediate.is_int8()) { |
2014 // Use sign-extended 8-bit immediate. | 2019 // Use sign-extended 8-bit immediate. |
2015 EmitUint8(0x83); | 2020 EmitUint8(0x83); |
2016 EmitOperand(rm, operand); | 2021 EmitOperand(rm, operand); |
2017 EmitUint8(immediate.value() & 0xFF); | 2022 EmitUint8(immediate.value() & 0xFF); |
2018 } else if (operand.IsRegister(RegX8632::Encoded_Reg_eax)) { | 2023 } else if (operand.IsRegister(RegX8632::Encoded_Reg_eax)) { |
2019 // Use short form if the destination is eax. | 2024 // Use short form if the destination is eax. |
2020 EmitUint8(0x05 + (rm << 3)); | 2025 EmitUint8(0x05 + (rm << 3)); |
2021 EmitImmediate(immediate); | 2026 EmitImmediate(Ty, immediate); |
2022 } else { | 2027 } else { |
2023 EmitUint8(0x81); | 2028 EmitUint8(0x81); |
2024 EmitOperand(rm, operand); | 2029 EmitOperand(rm, operand); |
2025 EmitImmediate(immediate); | 2030 EmitImmediate(Ty, immediate); |
2026 } | 2031 } |
2027 } | 2032 } |
2028 | 2033 |
2029 void AssemblerX86::EmitLabel(Label *label, intptr_t instruction_size) { | 2034 void AssemblerX86::EmitLabel(Label *label, intptr_t instruction_size) { |
2030 if (label->IsBound()) { | 2035 if (label->IsBound()) { |
2031 intptr_t offset = label->Position() - buffer_.Size(); | 2036 intptr_t offset = label->Position() - buffer_.Size(); |
2032 assert(offset <= 0); | 2037 assert(offset <= 0); |
2033 EmitInt32(offset - instruction_size); | 2038 EmitInt32(offset - instruction_size); |
2034 } else { | 2039 } else { |
2035 EmitLabelLink(label); | 2040 EmitLabelLink(label); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2067 void AssemblerX86::EmitGenericShift(int rm, const Operand &operand, | 2072 void AssemblerX86::EmitGenericShift(int rm, const Operand &operand, |
2068 GPRRegister shifter) { | 2073 GPRRegister shifter) { |
2069 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 2074 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
2070 assert(shifter == RegX8632::Encoded_Reg_ecx); | 2075 assert(shifter == RegX8632::Encoded_Reg_ecx); |
2071 EmitUint8(0xD3); | 2076 EmitUint8(0xD3); |
2072 EmitOperand(rm, Operand(operand)); | 2077 EmitOperand(rm, Operand(operand)); |
2073 } | 2078 } |
2074 | 2079 |
2075 } // end of namespace x86 | 2080 } // end of namespace x86 |
2076 } // end of namespace Ice | 2081 } // end of namespace Ice |
OLD | NEW |