| 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 |