Changeset 38487 in webkit for trunk/JavaScriptCore
- Timestamp:
- Nov 16, 2008, 10:27:06 PM (17 years ago)
- Location:
- trunk/JavaScriptCore
- Files:
-
- 1 added
- 1 deleted
- 4 edited
- 2 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r38482 r38487 1 2008-11-16 Geoffrey Garen <[email protected]> 2 3 Reviewed by Sam Weinig. 4 5 Moved masm => assembler and split "AssemblerBuffer.h" out of "X86Assembler.h". 6 7 Also renamed ENABLE_MASM to ENABLE_ASSEMBLER. 8 9 * GNUmakefile.am: 10 * JavaScriptCore.xcodeproj/project.pbxproj: 11 * assembler: Added. 12 * assembler/AssemblerBuffer.h: Copied from masm/X86Assembler.h. 13 (JSC::AssemblerBuffer::AssemblerBuffer): 14 (JSC::AssemblerBuffer::~AssemblerBuffer): 15 (JSC::AssemblerBuffer::ensureSpace): 16 (JSC::AssemblerBuffer::isAligned): 17 (JSC::AssemblerBuffer::putByteUnchecked): 18 (JSC::AssemblerBuffer::putByte): 19 (JSC::AssemblerBuffer::putShortUnchecked): 20 (JSC::AssemblerBuffer::putShort): 21 (JSC::AssemblerBuffer::putIntUnchecked): 22 (JSC::AssemblerBuffer::putInt): 23 (JSC::AssemblerBuffer::data): 24 (JSC::AssemblerBuffer::size): 25 (JSC::AssemblerBuffer::reset): 26 (JSC::AssemblerBuffer::executableCopy): 27 (JSC::AssemblerBuffer::grow): 28 * assembler/X86Assembler.h: Copied from masm/X86Assembler.h. 29 * masm: Removed. 30 * masm/X86Assembler.h: Removed. 31 * wtf/Platform.h: 32 1 33 2008-11-16 Geoffrey Garen <[email protected]> 2 34 -
trunk/JavaScriptCore/GNUmakefile.am
r38482 r38487 9 9 -I$(srcdir)/JavaScriptCore/runtime \ 10 10 -I$(srcdir)/JavaScriptCore/wrec \ 11 -I$(srcdir)/JavaScriptCore/ masm\11 -I$(srcdir)/JavaScriptCore/assembler \ 12 12 -I$(srcdir)/JavaScriptCore/wtf/unicode \ 13 13 -I$(top_builddir)/JavaScriptCore/pcre \ … … 114 114 JavaScriptCore/icu/unicode/utypes.h \ 115 115 JavaScriptCore/icu/unicode/uversion.h \ 116 JavaScriptCore/masm/X86Assembler.h \ 116 JavaScriptCore/assembler/X86Assembler.h \ 117 JavaScriptCore/assembler/AssemblerBuffer.h \ 117 118 JavaScriptCore/os-win32/stdbool.h \ 118 119 JavaScriptCore/os-win32/stdint.h \ -
trunk/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r38440 r38487 91 91 8683B02E0E636482004C19EE /* CTI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8683B02B0E636482004C19EE /* CTI.cpp */; }; 92 92 8683B02F0E636482004C19EE /* CTI.h in Headers */ = {isa = PBXBuildFile; fileRef = 8683B02C0E636482004C19EE /* CTI.h */; settings = {ATTRIBUTES = (Private, ); }; }; 93 869081410E640C89000D36ED /* X86Assembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 869081400E640C89000D36ED /* X86Assembler.h */; settings = {ATTRIBUTES = (Private, ); }; };94 93 869083150E6518D7000D36ED /* WREC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 869083130E6518D7000D36ED /* WREC.cpp */; }; 95 94 869083160E6518D7000D36ED /* WREC.h in Headers */ = {isa = PBXBuildFile; fileRef = 869083140E6518D7000D36ED /* WREC.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 124 123 95FDFA160E2299980006FB00 /* HeavyProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 95FDFA150E2299980006FB00 /* HeavyProfile.h */; }; 125 124 960097A60EBABB58007A7297 /* LabelScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 960097A50EBABB58007A7297 /* LabelScope.h */; }; 125 9688CB150ED12B4E001D649F /* AssemblerBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 9688CB130ED12B4E001D649F /* AssemblerBuffer.h */; }; 126 9688CB160ED12B4E001D649F /* X86Assembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 9688CB140ED12B4E001D649F /* X86Assembler.h */; }; 126 127 A72700900DAC6BBC00E548D7 /* JSNotAnObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A72700780DAC605600E548D7 /* JSNotAnObject.cpp */; }; 127 128 A72701B60DADE94900E548D7 /* ExceptionHelpers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A72701B40DADE94900E548D7 /* ExceptionHelpers.cpp */; }; … … 535 536 8683B02B0E636482004C19EE /* CTI.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CTI.cpp; path = VM/CTI.cpp; sourceTree = "<group>"; }; 536 537 8683B02C0E636482004C19EE /* CTI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CTI.h; path = VM/CTI.h; sourceTree = "<group>"; }; 537 869081400E640C89000D36ED /* X86Assembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = X86Assembler.h; sourceTree = "<group>"; };538 538 869083130E6518D7000D36ED /* WREC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WREC.cpp; sourceTree = "<group>"; }; 539 539 869083140E6518D7000D36ED /* WREC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WREC.h; sourceTree = "<group>"; }; … … 592 592 95FDFA150E2299980006FB00 /* HeavyProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HeavyProfile.h; path = profiler/HeavyProfile.h; sourceTree = "<group>"; }; 593 593 960097A50EBABB58007A7297 /* LabelScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LabelScope.h; sourceTree = "<group>"; }; 594 9688CB130ED12B4E001D649F /* AssemblerBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AssemblerBuffer.h; sourceTree = "<group>"; }; 595 9688CB140ED12B4E001D649F /* X86Assembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = X86Assembler.h; sourceTree = "<group>"; }; 594 596 A72700770DAC605600E548D7 /* JSNotAnObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSNotAnObject.h; sourceTree = "<group>"; }; 595 597 A72700780DAC605600E548D7 /* JSNotAnObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSNotAnObject.cpp; sourceTree = "<group>"; }; … … 826 828 F68EBB8C0255D4C601FF60F7 /* config.h */, 827 829 1432EBD70A34CAD400717B9F /* API */, 830 9688CB120ED12B4E001D649F /* assembler */, 828 831 7E39D81D0EC38EFA003AF11A /* bytecompiler */, 829 832 149B15DF0D81F887009CB8C7 /* compiler */, 830 833 1480DB9A0DDC2231003CFDF2 /* debugger */, 831 8690813F0E640C89000D36ED /* masm */,832 834 7E39D8370EC3A388003AF11A /* parser */, 833 835 65417203039E01F90058BFEB /* pcre */, … … 1288 1290 sourceTree = "<group>"; 1289 1291 }; 1290 8690813F0E640C89000D36ED /* masm */ = {1291 isa = PBXGroup;1292 children = (1293 869081400E640C89000D36ED /* X86Assembler.h */,1294 );1295 path = masm;1296 sourceTree = "<group>";1297 };1298 1292 869083120E6518D7000D36ED /* wrec */ = { 1299 1293 isa = PBXGroup; … … 1339 1333 sourceTree = "<group>"; 1340 1334 usesTabs = 0; 1335 }; 1336 9688CB120ED12B4E001D649F /* assembler */ = { 1337 isa = PBXGroup; 1338 children = ( 1339 9688CB130ED12B4E001D649F /* AssemblerBuffer.h */, 1340 9688CB140ED12B4E001D649F /* X86Assembler.h */, 1341 ); 1342 path = assembler; 1343 sourceTree = "<group>"; 1341 1344 }; 1342 1345 E195678D09E7CF1200B89D13 /* unicode */ = { … … 1561 1564 9534AAFB0E5B7A9600B8A45B /* JSProfilerPrivate.h in Headers */, 1562 1565 8683B02F0E636482004C19EE /* CTI.h in Headers */, 1563 869081410E640C89000D36ED /* X86Assembler.h in Headers */,1564 1566 869083160E6518D7000D36ED /* WREC.h in Headers */, 1565 1567 933040040E6A749400786E6A /* SmallStrings.h in Headers */, … … 1579 1581 7E4C89140ECA0F9A00DBEEEC /* EvalCodeCache.h in Headers */, 1580 1582 FE1B447A0ECCD73B004F4DD1 /* StdLibExtras.h in Headers */, 1583 9688CB150ED12B4E001D649F /* AssemblerBuffer.h in Headers */, 1584 9688CB160ED12B4E001D649F /* X86Assembler.h in Headers */, 1581 1585 ); 1582 1586 runOnlyForDeploymentPostprocessing = 0; -
trunk/JavaScriptCore/assembler/AssemblerBuffer.h
r38466 r38487 24 24 */ 25 25 26 #ifndef X86Assembler_h27 #define X86Assembler_h26 #ifndef AssemblerBuffer_h 27 #define AssemblerBuffer_h 28 28 29 #if ENABLE(MASM) && PLATFORM(X86) 29 #include <wtf/Platform.h> 30 31 #if ENABLE(ASSEMBLER) 30 32 31 33 #include <wtf/Assertions.h> 32 #include <wtf/AlwaysInline.h>33 34 #include <wtf/FastMalloc.h> 34 35 #if HAVE(MMAN)36 #include <sys/mman.h>37 #endif38 39 #include <string.h>40 35 41 36 namespace JSC { 42 37 43 class AssemblerBuffer { 44 public: 45 AssemblerBuffer(int capacity) 46 : m_buffer(static_cast<char*>(fastMalloc(capacity))) 47 , m_capacity(capacity) 48 , m_size(0) 49 { 50 } 51 52 ~AssemblerBuffer() 53 { 54 fastFree(m_buffer); 55 } 56 57 void ensureSpace(int space) 58 { 59 if (m_size > m_capacity - space) 60 grow(); 61 } 62 63 bool isAligned(int alignment) 64 { 65 return !(m_size & (alignment - 1)); 66 } 67 68 void putByteUnchecked(int value) 69 { 70 ASSERT(!(m_size > m_capacity - 4)); 71 m_buffer[m_size] = value; 72 m_size++; 73 } 74 75 void putByte(int value) 76 { 77 if (m_size > m_capacity - 4) 78 grow(); 79 putByteUnchecked(value); 80 } 81 82 void putShortUnchecked(int value) 83 { 84 ASSERT(!(m_size > m_capacity - 4)); 85 *reinterpret_cast<short*>(&m_buffer[m_size]) = value; 86 m_size += 2; 87 } 88 89 void putShort(int value) 90 { 91 if (m_size > m_capacity - 4) 92 grow(); 93 putShortUnchecked(value); 94 } 95 96 void putIntUnchecked(int value) 97 { 98 *reinterpret_cast<int*>(&m_buffer[m_size]) = value; 99 m_size += 4; 100 } 101 102 void putInt(int value) 103 { 104 if (m_size > m_capacity - 4) 105 grow(); 106 putIntUnchecked(value); 107 } 108 109 void* data() 110 { 111 return m_buffer; 112 } 113 114 int size() 115 { 116 return m_size; 117 } 118 119 AssemblerBuffer* reset() 120 { 121 m_size = 0; 122 return this; 123 } 124 125 void* executableCopy() 126 { 127 if (!m_size) 128 return 0; 129 130 void* result = WTF::fastMallocExecutable(m_size); 131 132 if (!result) 133 return 0; 134 135 return memcpy(result, m_buffer, m_size); 136 } 137 138 private: 139 void grow() 140 { 141 m_capacity += m_capacity / 2; 142 m_buffer = static_cast<char*>(fastRealloc(m_buffer, m_capacity)); 143 } 144 145 char* m_buffer; 146 int m_capacity; 147 int m_size; 148 }; 149 150 #define MODRM(type, reg, rm) ((type << 6) | (reg << 3) | (rm)) 151 #define SIB(type, reg, rm) MODRM(type, reg, rm) 152 #define CAN_SIGN_EXTEND_8_32(value) (value == ((int)(signed char)value)) 153 154 namespace X86 { 155 typedef enum { 156 eax, 157 ecx, 158 edx, 159 ebx, 160 esp, 161 ebp, 162 esi, 163 edi, 164 165 noBase = ebp, 166 hasSib = esp, 167 noScale = esp, 168 } RegisterID; 169 170 typedef enum { 171 xmm0, 172 xmm1, 173 xmm2, 174 xmm3, 175 xmm4, 176 xmm5, 177 xmm6, 178 xmm7, 179 } XMMRegisterID; 180 } 181 182 class X86Assembler { 183 public: 184 typedef X86::RegisterID RegisterID; 185 typedef X86::XMMRegisterID XMMRegisterID; 186 187 typedef enum { 188 OP_ADD_EvGv = 0x01, 189 OP_ADD_GvEv = 0x03, 190 OP_OR_EvGv = 0x09, 191 OP_OR_GvEv = 0x0B, 192 OP_2BYTE_ESCAPE = 0x0F, 193 OP_AND_EvGv = 0x21, 194 OP_SUB_EvGv = 0x29, 195 OP_SUB_GvEv = 0x2B, 196 PRE_PREDICT_BRANCH_NOT_TAKEN = 0x2E, 197 OP_XOR_EvGv = 0x31, 198 OP_CMP_EvGv = 0x39, 199 OP_CMP_GvEv = 0x3B, 200 OP_PUSH_EAX = 0x50, 201 OP_POP_EAX = 0x58, 202 PRE_OPERAND_SIZE = 0x66, 203 PRE_SSE_66 = 0x66, 204 OP_PUSH_Iz = 0x68, 205 OP_IMUL_GvEvIz = 0x69, 206 OP_GROUP1_EvIz = 0x81, 207 OP_GROUP1_EvIb = 0x83, 208 OP_TEST_EvGv = 0x85, 209 OP_MOV_EvGv = 0x89, 210 OP_MOV_GvEv = 0x8B, 211 OP_LEA = 0x8D, 212 OP_GROUP1A_Ev = 0x8F, 213 OP_CDQ = 0x99, 214 OP_SETE = 0x94, 215 OP_SETNE = 0x95, 216 OP_GROUP2_EvIb = 0xC1, 217 OP_RET = 0xC3, 218 OP_GROUP11_EvIz = 0xC7, 219 OP_INT3 = 0xCC, 220 OP_GROUP2_Ev1 = 0xD1, 221 OP_GROUP2_EvCL = 0xD3, 222 OP_CALL_rel32 = 0xE8, 223 OP_JMP_rel32 = 0xE9, 224 PRE_SSE_F2 = 0xF2, 225 OP_HLT = 0xF4, 226 OP_GROUP3_Ev = 0xF7, 227 OP_GROUP3_EvIz = 0xF7, // OP_GROUP3_Ev has an immediate, when instruction is a test. 228 OP_GROUP5_Ev = 0xFF, 229 230 OP2_MOVSD_VsdWsd = 0x10, 231 OP2_MOVSD_WsdVsd = 0x11, 232 OP2_CVTSI2SD_VsdEd = 0x2A, 233 OP2_CVTTSD2SI_GdWsd = 0x2C, 234 OP2_UCOMISD_VsdWsd = 0x2E, 235 OP2_XORPD_VsdWsd = 0x57, 236 OP2_ADDSD_VsdWsd = 0x58, 237 OP2_MULSD_VsdWsd = 0x59, 238 OP2_SUBSD_VsdWsd = 0x5C, 239 OP2_MOVD_EdVd = 0x7E, 240 OP2_JO_rel32 = 0x80, 241 OP2_JB_rel32 = 0x82, 242 OP2_JAE_rel32 = 0x83, 243 OP2_JE_rel32 = 0x84, 244 OP2_JNE_rel32 = 0x85, 245 OP2_JBE_rel32 = 0x86, 246 OP2_JA_rel32 = 0x87, 247 OP2_JS_rel32 = 0x88, 248 OP2_JP_rel32 = 0x8A, 249 OP2_JL_rel32 = 0x8C, 250 OP2_JGE_rel32 = 0x8D, 251 OP2_JLE_rel32 = 0x8E, 252 OP2_JG_rel32 = 0x8F, 253 OP2_IMUL_GvEv = 0xAF, 254 OP2_MOVZX_GvEb = 0xB6, 255 OP2_MOVZX_GvEw = 0xB7, 256 OP2_PEXTRW_GdUdIb = 0xC5, 257 258 GROUP1_OP_ADD = 0, 259 GROUP1_OP_OR = 1, 260 GROUP1_OP_AND = 4, 261 GROUP1_OP_SUB = 5, 262 GROUP1_OP_XOR = 6, 263 GROUP1_OP_CMP = 7, 264 265 GROUP1A_OP_POP = 0, 266 267 GROUP2_OP_SHL = 4, 268 GROUP2_OP_SAR = 7, 269 270 GROUP3_OP_TEST = 0, 271 GROUP3_OP_NEG = 3, 272 GROUP3_OP_IDIV = 7, 273 274 GROUP5_OP_CALLN = 2, 275 GROUP5_OP_JMPN = 4, 276 GROUP5_OP_PUSH = 6, 277 278 GROUP11_MOV = 0, 279 } OpcodeID; 280 281 static const int maxInstructionSize = 16; 282 283 X86Assembler(AssemblerBuffer* m_buffer) 284 : m_buffer(m_buffer) 285 { 286 m_buffer->reset(); 287 } 288 289 void emitInt3() 290 { 291 m_buffer->putByte(OP_INT3); 292 } 293 294 void pushl_r(RegisterID reg) 295 { 296 m_buffer->putByte(OP_PUSH_EAX + reg); 297 } 298 299 void pushl_m(int offset, RegisterID base) 300 { 301 m_buffer->putByte(OP_GROUP5_Ev); 302 emitModRm_opm(GROUP5_OP_PUSH, base, offset); 303 } 304 305 void pushl_i32(int imm) 306 { 307 m_buffer->putByte(OP_PUSH_Iz); 308 m_buffer->putInt(imm); 309 } 310 311 void popl_r(RegisterID reg) 312 { 313 m_buffer->putByte(OP_POP_EAX + reg); 314 } 315 316 void popl_m(int offset, RegisterID base) 317 { 318 m_buffer->putByte(OP_GROUP1A_Ev); 319 emitModRm_opm(GROUP1A_OP_POP, base, offset); 320 } 321 322 void movl_rr(RegisterID src, RegisterID dst) 323 { 324 m_buffer->putByte(OP_MOV_EvGv); 325 emitModRm_rr(src, dst); 326 } 327 328 void addl_rr(RegisterID src, RegisterID dst) 329 { 330 m_buffer->putByte(OP_ADD_EvGv); 331 emitModRm_rr(src, dst); 332 } 333 334 void addl_i8r(int imm, RegisterID dst) 335 { 336 m_buffer->putByte(OP_GROUP1_EvIb); 337 emitModRm_opr(GROUP1_OP_ADD, dst); 338 m_buffer->putByte(imm); 339 } 340 341 void addl_i8m(int imm, void* addr) 342 { 343 m_buffer->putByte(OP_GROUP1_EvIb); 344 emitModRm_opm(GROUP1_OP_ADD, addr); 345 m_buffer->putByte(imm); 346 } 347 348 void addl_i32r(int imm, RegisterID dst) 349 { 350 m_buffer->putByte(OP_GROUP1_EvIz); 351 emitModRm_opr(GROUP1_OP_ADD, dst); 352 m_buffer->putInt(imm); 353 } 354 355 void addl_mr(int offset, RegisterID base, RegisterID dst) 356 { 357 m_buffer->putByte(OP_ADD_GvEv); 358 emitModRm_rm(dst, base, offset); 359 } 360 361 void andl_rr(RegisterID src, RegisterID dst) 362 { 363 m_buffer->putByte(OP_AND_EvGv); 364 emitModRm_rr(src, dst); 365 } 366 367 void andl_i32r(int imm, RegisterID dst) 368 { 369 m_buffer->putByte(OP_GROUP1_EvIz); 370 emitModRm_opr(GROUP1_OP_AND, dst); 371 m_buffer->putInt(imm); 372 } 373 374 void cmpl_i8r(int imm, RegisterID dst) 375 { 376 m_buffer->putByte(OP_GROUP1_EvIb); 377 emitModRm_opr(GROUP1_OP_CMP, dst); 378 m_buffer->putByte(imm); 379 } 380 381 void cmpl_rr(RegisterID src, RegisterID dst) 382 { 383 m_buffer->putByte(OP_CMP_EvGv); 384 emitModRm_rr(src, dst); 385 } 386 387 void cmpl_rm(RegisterID src, int offset, RegisterID base) 388 { 389 m_buffer->putByte(OP_CMP_EvGv); 390 emitModRm_rm(src, base, offset); 391 } 392 393 void cmpl_mr(int offset, RegisterID base, RegisterID dst) 394 { 395 m_buffer->putByte(OP_CMP_GvEv); 396 emitModRm_rm(dst, base, offset); 397 } 398 399 void cmpl_i32r(int imm, RegisterID dst) 400 { 401 m_buffer->putByte(OP_GROUP1_EvIz); 402 emitModRm_opr(GROUP1_OP_CMP, dst); 403 m_buffer->putInt(imm); 404 } 405 406 void cmpl_i32m(int imm, RegisterID dst) 407 { 408 m_buffer->putByte(OP_GROUP1_EvIz); 409 emitModRm_opm(GROUP1_OP_CMP, dst); 410 m_buffer->putInt(imm); 411 } 412 413 void cmpl_i32m(int imm, int offset, RegisterID dst) 414 { 415 m_buffer->putByte(OP_GROUP1_EvIz); 416 emitModRm_opm(GROUP1_OP_CMP, dst, offset); 417 m_buffer->putInt(imm); 418 } 419 420 void cmpl_i32m(int imm, void* addr) 421 { 422 m_buffer->putByte(OP_GROUP1_EvIz); 423 emitModRm_opm(GROUP1_OP_CMP, addr); 424 m_buffer->putInt(imm); 425 } 426 427 void cmpl_i8m(int imm, int offset, RegisterID base, RegisterID index, int scale) 428 { 429 m_buffer->putByte(OP_GROUP1_EvIb); 430 emitModRm_opmsib(GROUP1_OP_CMP, base, index, scale, offset); 431 m_buffer->putByte(imm); 432 } 433 434 void cmpw_rm(RegisterID src, RegisterID base, RegisterID index, int scale) 435 { 436 m_buffer->putByte(PRE_OPERAND_SIZE); 437 m_buffer->putByte(OP_CMP_EvGv); 438 emitModRm_rmsib(src, base, index, scale); 439 } 440 441 void sete_r(RegisterID dst) 442 { 443 m_buffer->putByte(OP_2BYTE_ESCAPE); 444 m_buffer->putByte(OP_SETE); 445 m_buffer->putByte(MODRM(3, 0, dst)); 446 } 447 448 void setz_r(RegisterID dst) 449 { 450 sete_r(dst); 451 } 452 453 void setne_r(RegisterID dst) 454 { 455 m_buffer->putByte(OP_2BYTE_ESCAPE); 456 m_buffer->putByte(OP_SETNE); 457 m_buffer->putByte(MODRM(3, 0, dst)); 458 } 459 460 void setnz_r(RegisterID dst) 461 { 462 setne_r(dst); 463 } 464 465 void orl_rr(RegisterID src, RegisterID dst) 466 { 467 m_buffer->putByte(OP_OR_EvGv); 468 emitModRm_rr(src, dst); 469 } 470 471 void orl_mr(int offset, RegisterID base, RegisterID dst) 472 { 473 m_buffer->putByte(OP_OR_GvEv); 474 emitModRm_rm(dst, base, offset); 475 } 476 477 void orl_i32r(int imm, RegisterID dst) 478 { 479 m_buffer->putByte(OP_GROUP1_EvIb); 480 emitModRm_opr(GROUP1_OP_OR, dst); 481 m_buffer->putByte(imm); 482 } 483 484 void subl_rr(RegisterID src, RegisterID dst) 485 { 486 m_buffer->putByte(OP_SUB_EvGv); 487 emitModRm_rr(src, dst); 488 } 489 490 void subl_i8r(int imm, RegisterID dst) 491 { 492 m_buffer->putByte(OP_GROUP1_EvIb); 493 emitModRm_opr(GROUP1_OP_SUB, dst); 494 m_buffer->putByte(imm); 495 } 496 497 void subl_i8m(int imm, void* addr) 498 { 499 m_buffer->putByte(OP_GROUP1_EvIb); 500 emitModRm_opm(GROUP1_OP_SUB, addr); 501 m_buffer->putByte(imm); 502 } 503 504 void subl_i32r(int imm, RegisterID dst) 505 { 506 m_buffer->putByte(OP_GROUP1_EvIz); 507 emitModRm_opr(GROUP1_OP_SUB, dst); 508 m_buffer->putInt(imm); 509 } 510 511 void subl_mr(int offset, RegisterID base, RegisterID dst) 512 { 513 m_buffer->putByte(OP_SUB_GvEv); 514 emitModRm_rm(dst, base, offset); 515 } 516 517 void testl_i32r(int imm, RegisterID dst) 518 { 519 m_buffer->ensureSpace(maxInstructionSize); 520 m_buffer->putByteUnchecked(OP_GROUP3_EvIz); 521 emitModRm_opr_Unchecked(GROUP3_OP_TEST, dst); 522 m_buffer->putIntUnchecked(imm); 523 } 524 525 void testl_i32m(int imm, RegisterID dst) 526 { 527 m_buffer->putByte(OP_GROUP3_EvIz); 528 emitModRm_opm(GROUP3_OP_TEST, dst); 529 m_buffer->putInt(imm); 530 } 531 532 void testl_i32m(int imm, int offset, RegisterID dst) 533 { 534 m_buffer->putByte(OP_GROUP3_EvIz); 535 emitModRm_opm(GROUP3_OP_TEST, dst, offset); 536 m_buffer->putInt(imm); 537 } 538 539 void testl_rr(RegisterID src, RegisterID dst) 540 { 541 m_buffer->putByte(OP_TEST_EvGv); 542 emitModRm_rr(src, dst); 543 } 544 545 void xorl_i8r(int imm, RegisterID dst) 546 { 547 m_buffer->putByte(OP_GROUP1_EvIb); 548 emitModRm_opr(GROUP1_OP_XOR, dst); 549 m_buffer->putByte(imm); 550 } 551 552 void xorl_rr(RegisterID src, RegisterID dst) 553 { 554 m_buffer->putByte(OP_XOR_EvGv); 555 emitModRm_rr(src, dst); 556 } 557 558 void sarl_i8r(int imm, RegisterID dst) 559 { 560 if (imm == 1) { 561 m_buffer->putByte(OP_GROUP2_Ev1); 562 emitModRm_opr(GROUP2_OP_SAR, dst); 563 } else { 564 m_buffer->putByte(OP_GROUP2_EvIb); 565 emitModRm_opr(GROUP2_OP_SAR, dst); 566 m_buffer->putByte(imm); 567 } 568 } 569 570 void sarl_CLr(RegisterID dst) 571 { 572 m_buffer->putByte(OP_GROUP2_EvCL); 573 emitModRm_opr(GROUP2_OP_SAR, dst); 574 } 575 576 void shl_i8r(int imm, RegisterID dst) 577 { 578 if (imm == 1) { 579 m_buffer->putByte(OP_GROUP2_Ev1); 580 emitModRm_opr(GROUP2_OP_SHL, dst); 581 } else { 582 m_buffer->putByte(OP_GROUP2_EvIb); 583 emitModRm_opr(GROUP2_OP_SHL, dst); 584 m_buffer->putByte(imm); 585 } 586 } 587 588 void shll_CLr(RegisterID dst) 589 { 590 m_buffer->putByte(OP_GROUP2_EvCL); 591 emitModRm_opr(GROUP2_OP_SHL, dst); 592 } 593 594 void imull_rr(RegisterID src, RegisterID dst) 595 { 596 m_buffer->putByte(OP_2BYTE_ESCAPE); 597 m_buffer->putByte(OP2_IMUL_GvEv); 598 emitModRm_rr(dst, src); 599 } 600 601 void imull_i32r(RegisterID src, int32_t value, RegisterID dst) 602 { 603 m_buffer->putByte(OP_IMUL_GvEvIz); 604 emitModRm_rr(dst, src); 605 m_buffer->putInt(value); 606 } 607 608 void idivl_r(RegisterID dst) 609 { 610 m_buffer->putByte(OP_GROUP3_Ev); 611 emitModRm_opr(GROUP3_OP_IDIV, dst); 612 } 613 614 void negl_r(RegisterID dst) 615 { 616 m_buffer->putByte(OP_GROUP3_Ev); 617 emitModRm_opr(GROUP3_OP_NEG, dst); 618 } 619 620 void cdq() 621 { 622 m_buffer->putByte(OP_CDQ); 623 } 624 625 void movl_mr(RegisterID base, RegisterID dst) 626 { 627 m_buffer->putByte(OP_MOV_GvEv); 628 emitModRm_rm(dst, base); 629 } 630 631 void movl_mr(int offset, RegisterID base, RegisterID dst) 632 { 633 m_buffer->ensureSpace(maxInstructionSize); 634 m_buffer->putByteUnchecked(OP_MOV_GvEv); 635 emitModRm_rm_Unchecked(dst, base, offset); 636 } 637 638 void movl_mr(void* addr, RegisterID dst) 639 { 640 m_buffer->putByte(OP_MOV_GvEv); 641 emitModRm_rm(dst, addr); 642 } 643 644 void movl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst) 645 { 646 m_buffer->putByte(OP_MOV_GvEv); 647 emitModRm_rmsib(dst, base, index, scale, offset); 648 } 649 650 void movzbl_rr(RegisterID src, RegisterID dst) 651 { 652 m_buffer->putByte(OP_2BYTE_ESCAPE); 653 m_buffer->putByte(OP2_MOVZX_GvEb); 654 emitModRm_rr(dst, src); 655 } 656 657 void movzwl_mr(int offset, RegisterID base, RegisterID dst) 658 { 659 m_buffer->putByte(OP_2BYTE_ESCAPE); 660 m_buffer->putByte(OP2_MOVZX_GvEw); 661 emitModRm_rm(dst, base, offset); 662 } 663 664 void movzwl_mr(RegisterID base, RegisterID index, int scale, RegisterID dst) 665 { 666 m_buffer->putByte(OP_2BYTE_ESCAPE); 667 m_buffer->putByte(OP2_MOVZX_GvEw); 668 emitModRm_rmsib(dst, base, index, scale); 669 } 670 671 void movzwl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst) 672 { 673 m_buffer->putByte(OP_2BYTE_ESCAPE); 674 m_buffer->putByte(OP2_MOVZX_GvEw); 675 emitModRm_rmsib(dst, base, index, scale, offset); 676 } 677 678 void movl_rm(RegisterID src, RegisterID base) 679 { 680 m_buffer->putByte(OP_MOV_EvGv); 681 emitModRm_rm(src, base); 682 } 683 684 void movl_rm(RegisterID src, int offset, RegisterID base) 685 { 686 m_buffer->ensureSpace(maxInstructionSize); 687 m_buffer->putByteUnchecked(OP_MOV_EvGv); 688 emitModRm_rm_Unchecked(src, base, offset); 689 } 690 691 void movl_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale) 692 { 693 m_buffer->putByte(OP_MOV_EvGv); 694 emitModRm_rmsib(src, base, index, scale, offset); 695 } 696 697 void movl_i32r(int imm, RegisterID dst) 698 { 699 m_buffer->putByte(OP_GROUP11_EvIz); 700 emitModRm_opr(GROUP11_MOV, dst); 701 m_buffer->putInt(imm); 702 } 703 704 void movl_i32m(int imm, int offset, RegisterID base) 705 { 706 m_buffer->ensureSpace(maxInstructionSize); 707 m_buffer->putByteUnchecked(OP_GROUP11_EvIz); 708 emitModRm_opm_Unchecked(GROUP11_MOV, base, offset); 709 m_buffer->putIntUnchecked(imm); 710 } 711 712 void movl_i32m(int imm, void* addr) 713 { 714 m_buffer->putByte(OP_GROUP11_EvIz); 715 emitModRm_opm(GROUP11_MOV, addr); 716 m_buffer->putInt(imm); 717 } 718 719 void leal_mr(int offset, RegisterID base, RegisterID dst) 720 { 721 m_buffer->putByte(OP_LEA); 722 emitModRm_rm(dst, base, offset); 723 } 724 725 void leal_mr(int offset, RegisterID index, int scale, RegisterID dst) 726 { 727 m_buffer->putByte(OP_LEA); 728 emitModRm_rmsib(dst, X86::noBase, index, scale, offset); 729 } 730 731 void ret() 732 { 733 m_buffer->putByte(OP_RET); 734 } 735 736 void jmp_r(RegisterID dst) 737 { 738 m_buffer->putByte(OP_GROUP5_Ev); 739 emitModRm_opr(GROUP5_OP_JMPN, dst); 740 } 741 742 void jmp_m(int offset, RegisterID base) 743 { 744 m_buffer->putByte(OP_GROUP5_Ev); 745 emitModRm_opm(GROUP5_OP_JMPN, base, offset); 746 } 747 748 void movsd_mr(int offset, RegisterID base, XMMRegisterID dst) 749 { 750 m_buffer->putByte(PRE_SSE_F2); 751 m_buffer->putByte(OP_2BYTE_ESCAPE); 752 m_buffer->putByte(OP2_MOVSD_VsdWsd); 753 emitModRm_rm((RegisterID)dst, base, offset); 754 } 755 756 void xorpd_mr(void* addr, XMMRegisterID dst) 757 { 758 m_buffer->putByte(PRE_SSE_66); 759 m_buffer->putByte(OP_2BYTE_ESCAPE); 760 m_buffer->putByte(OP2_XORPD_VsdWsd); 761 emitModRm_rm((RegisterID)dst, addr); 762 } 763 764 void movsd_rm(XMMRegisterID src, int offset, RegisterID base) 765 { 766 m_buffer->putByte(PRE_SSE_F2); 767 m_buffer->putByte(OP_2BYTE_ESCAPE); 768 m_buffer->putByte(OP2_MOVSD_WsdVsd); 769 emitModRm_rm((RegisterID)src, base, offset); 770 } 771 772 void movd_rr(XMMRegisterID src, RegisterID dst) 773 { 774 m_buffer->putByte(PRE_SSE_66); 775 m_buffer->putByte(OP_2BYTE_ESCAPE); 776 m_buffer->putByte(OP2_MOVD_EdVd); 777 emitModRm_rr((RegisterID)src, dst); 778 } 779 780 void cvtsi2sd_rr(RegisterID src, XMMRegisterID dst) 781 { 782 m_buffer->putByte(PRE_SSE_F2); 783 m_buffer->putByte(OP_2BYTE_ESCAPE); 784 m_buffer->putByte(OP2_CVTSI2SD_VsdEd); 785 emitModRm_rr((RegisterID)dst, src); 786 } 787 788 void cvttsd2si_rr(XMMRegisterID src, RegisterID dst) 789 { 790 m_buffer->putByte(PRE_SSE_F2); 791 m_buffer->putByte(OP_2BYTE_ESCAPE); 792 m_buffer->putByte(OP2_CVTTSD2SI_GdWsd); 793 emitModRm_rr(dst, (RegisterID)src); 794 } 795 796 void addsd_mr(int offset, RegisterID base, XMMRegisterID dst) 797 { 798 m_buffer->putByte(PRE_SSE_F2); 799 m_buffer->putByte(OP_2BYTE_ESCAPE); 800 m_buffer->putByte(OP2_ADDSD_VsdWsd); 801 emitModRm_rm((RegisterID)dst, base, offset); 802 } 803 804 void subsd_mr(int offset, RegisterID base, XMMRegisterID dst) 805 { 806 m_buffer->putByte(PRE_SSE_F2); 807 m_buffer->putByte(OP_2BYTE_ESCAPE); 808 m_buffer->putByte(OP2_SUBSD_VsdWsd); 809 emitModRm_rm((RegisterID)dst, base, offset); 810 } 811 812 void mulsd_mr(int offset, RegisterID base, XMMRegisterID dst) 813 { 814 m_buffer->putByte(PRE_SSE_F2); 815 m_buffer->putByte(OP_2BYTE_ESCAPE); 816 m_buffer->putByte(OP2_MULSD_VsdWsd); 817 emitModRm_rm((RegisterID)dst, base, offset); 818 } 819 820 void addsd_rr(XMMRegisterID src, XMMRegisterID dst) 821 { 822 m_buffer->putByte(PRE_SSE_F2); 823 m_buffer->putByte(OP_2BYTE_ESCAPE); 824 m_buffer->putByte(OP2_ADDSD_VsdWsd); 825 emitModRm_rr((RegisterID)dst, (RegisterID)src); 826 } 827 828 void subsd_rr(XMMRegisterID src, XMMRegisterID dst) 829 { 830 m_buffer->putByte(PRE_SSE_F2); 831 m_buffer->putByte(OP_2BYTE_ESCAPE); 832 m_buffer->putByte(OP2_SUBSD_VsdWsd); 833 emitModRm_rr((RegisterID)dst, (RegisterID)src); 834 } 835 836 void mulsd_rr(XMMRegisterID src, XMMRegisterID dst) 837 { 838 m_buffer->putByte(PRE_SSE_F2); 839 m_buffer->putByte(OP_2BYTE_ESCAPE); 840 m_buffer->putByte(OP2_MULSD_VsdWsd); 841 emitModRm_rr((RegisterID)dst, (RegisterID)src); 842 } 843 844 void ucomis_rr(XMMRegisterID src, XMMRegisterID dst) 845 { 846 m_buffer->putByte(PRE_SSE_66); 847 m_buffer->putByte(OP_2BYTE_ESCAPE); 848 m_buffer->putByte(OP2_UCOMISD_VsdWsd); 849 emitModRm_rr((RegisterID)dst, (RegisterID)src); 850 } 851 852 void pextrw_irr(int whichWord, XMMRegisterID src, RegisterID dst) 853 { 854 m_buffer->putByte(PRE_SSE_66); 855 m_buffer->putByte(OP_2BYTE_ESCAPE); 856 m_buffer->putByte(OP2_PEXTRW_GdUdIb); 857 emitModRm_rr(dst, (RegisterID)src); 858 m_buffer->putByte(whichWord); 859 } 860 861 // Opaque label types 862 863 class JmpSrc { 864 friend class X86Assembler; 38 class AssemblerBuffer { 865 39 public: 866 JmpSrc() 867 : m_offset(-1) 40 AssemblerBuffer(int capacity) 41 : m_buffer(static_cast<char*>(fastMalloc(capacity))) 42 , m_capacity(capacity) 43 , m_size(0) 868 44 { 869 45 } 870 46 871 private: 872 JmpSrc(int offset) 873 : m_offset(offset) 47 ~AssemblerBuffer() 874 48 { 49 fastFree(m_buffer); 875 50 } 876 51 877 int m_offset; 878 }; 879 880 class JmpDst { 881 friend class X86Assembler; 882 public: 883 JmpDst() 884 : m_offset(-1) 52 void ensureSpace(int space) 885 53 { 54 if (m_size > m_capacity - space) 55 grow(); 56 } 57 58 bool isAligned(int alignment) 59 { 60 return !(m_size & (alignment - 1)); 61 } 62 63 void putByteUnchecked(int value) 64 { 65 ASSERT(!(m_size > m_capacity - 4)); 66 m_buffer[m_size] = value; 67 m_size++; 68 } 69 70 void putByte(int value) 71 { 72 if (m_size > m_capacity - 4) 73 grow(); 74 putByteUnchecked(value); 75 } 76 77 void putShortUnchecked(int value) 78 { 79 ASSERT(!(m_size > m_capacity - 4)); 80 *reinterpret_cast<short*>(&m_buffer[m_size]) = value; 81 m_size += 2; 82 } 83 84 void putShort(int value) 85 { 86 if (m_size > m_capacity - 4) 87 grow(); 88 putShortUnchecked(value); 89 } 90 91 void putIntUnchecked(int value) 92 { 93 *reinterpret_cast<int*>(&m_buffer[m_size]) = value; 94 m_size += 4; 95 } 96 97 void putInt(int value) 98 { 99 if (m_size > m_capacity - 4) 100 grow(); 101 putIntUnchecked(value); 102 } 103 104 void* data() 105 { 106 return m_buffer; 107 } 108 109 int size() 110 { 111 return m_size; 112 } 113 114 AssemblerBuffer* reset() 115 { 116 m_size = 0; 117 return this; 118 } 119 120 void* executableCopy() 121 { 122 if (!m_size) 123 return 0; 124 125 void* result = WTF::fastMallocExecutable(m_size); 126 127 if (!result) 128 return 0; 129 130 return memcpy(result, m_buffer, m_size); 886 131 } 887 132 888 133 private: 889 JmpDst(int offset) 890 : m_offset(offset) 134 void grow() 891 135 { 136 m_capacity += m_capacity / 2; 137 m_buffer = static_cast<char*>(fastRealloc(m_buffer, m_capacity)); 892 138 } 893 139 894 int m_offset; 140 char* m_buffer; 141 int m_capacity; 142 int m_size; 895 143 }; 896 897 // FIXME: make this point to a global label, linked later.898 JmpSrc emitCall()899 {900 m_buffer->putByte(OP_CALL_rel32);901 m_buffer->putInt(0);902 return JmpSrc(m_buffer->size());903 }904 905 JmpSrc emitCall(RegisterID dst)906 {907 m_buffer->putByte(OP_GROUP5_Ev);908 emitModRm_opr(GROUP5_OP_CALLN, dst);909 return JmpSrc(m_buffer->size());910 }911 912 JmpDst label()913 {914 return JmpDst(m_buffer->size());915 }916 917 JmpDst align(int alignment)918 {919 while (!m_buffer->isAligned(alignment))920 m_buffer->putByte(OP_HLT);921 922 return label();923 }924 925 JmpSrc emitUnlinkedJmp()926 {927 m_buffer->putByte(OP_JMP_rel32);928 m_buffer->putInt(0);929 return JmpSrc(m_buffer->size());930 }931 932 JmpSrc emitUnlinkedJne()933 {934 m_buffer->putByte(OP_2BYTE_ESCAPE);935 m_buffer->putByte(OP2_JNE_rel32);936 m_buffer->putInt(0);937 return JmpSrc(m_buffer->size());938 }939 940 JmpSrc emitUnlinkedJnz()941 {942 return emitUnlinkedJne();943 }944 945 JmpSrc emitUnlinkedJe()946 {947 m_buffer->ensureSpace(maxInstructionSize);948 m_buffer->putByteUnchecked(OP_2BYTE_ESCAPE);949 m_buffer->putByteUnchecked(OP2_JE_rel32);950 m_buffer->putIntUnchecked(0);951 return JmpSrc(m_buffer->size());952 }953 954 JmpSrc emitUnlinkedJl()955 {956 m_buffer->putByte(OP_2BYTE_ESCAPE);957 m_buffer->putByte(OP2_JL_rel32);958 m_buffer->putInt(0);959 return JmpSrc(m_buffer->size());960 }961 962 JmpSrc emitUnlinkedJb()963 {964 m_buffer->putByte(OP_2BYTE_ESCAPE);965 m_buffer->putByte(OP2_JB_rel32);966 m_buffer->putInt(0);967 return JmpSrc(m_buffer->size());968 }969 970 JmpSrc emitUnlinkedJle()971 {972 m_buffer->putByte(OP_2BYTE_ESCAPE);973 m_buffer->putByte(OP2_JLE_rel32);974 m_buffer->putInt(0);975 return JmpSrc(m_buffer->size());976 }977 978 JmpSrc emitUnlinkedJbe()979 {980 m_buffer->putByte(OP_2BYTE_ESCAPE);981 m_buffer->putByte(OP2_JBE_rel32);982 m_buffer->putInt(0);983 return JmpSrc(m_buffer->size());984 }985 986 JmpSrc emitUnlinkedJge()987 {988 m_buffer->putByte(OP_2BYTE_ESCAPE);989 m_buffer->putByte(OP2_JGE_rel32);990 m_buffer->putInt(0);991 return JmpSrc(m_buffer->size());992 }993 994 JmpSrc emitUnlinkedJg()995 {996 m_buffer->putByte(OP_2BYTE_ESCAPE);997 m_buffer->putByte(OP2_JG_rel32);998 m_buffer->putInt(0);999 return JmpSrc(m_buffer->size());1000 }1001 1002 JmpSrc emitUnlinkedJa()1003 {1004 m_buffer->putByte(OP_2BYTE_ESCAPE);1005 m_buffer->putByte(OP2_JA_rel32);1006 m_buffer->putInt(0);1007 return JmpSrc(m_buffer->size());1008 }1009 1010 JmpSrc emitUnlinkedJae()1011 {1012 m_buffer->putByte(OP_2BYTE_ESCAPE);1013 m_buffer->putByte(OP2_JAE_rel32);1014 m_buffer->putInt(0);1015 return JmpSrc(m_buffer->size());1016 }1017 1018 JmpSrc emitUnlinkedJo()1019 {1020 m_buffer->putByte(OP_2BYTE_ESCAPE);1021 m_buffer->putByte(OP2_JO_rel32);1022 m_buffer->putInt(0);1023 return JmpSrc(m_buffer->size());1024 }1025 1026 JmpSrc emitUnlinkedJp()1027 {1028 m_buffer->putByte(OP_2BYTE_ESCAPE);1029 m_buffer->putByte(OP2_JP_rel32);1030 m_buffer->putInt(0);1031 return JmpSrc(m_buffer->size());1032 }1033 1034 JmpSrc emitUnlinkedJs()1035 {1036 m_buffer->putByte(OP_2BYTE_ESCAPE);1037 m_buffer->putByte(OP2_JS_rel32);1038 m_buffer->putInt(0);1039 return JmpSrc(m_buffer->size());1040 }1041 1042 void emitPredictionNotTaken()1043 {1044 m_buffer->putByte(PRE_PREDICT_BRANCH_NOT_TAKEN);1045 }1046 1047 void link(JmpSrc from, JmpDst to)1048 {1049 ASSERT(to.m_offset != -1);1050 ASSERT(from.m_offset != -1);1051 1052 reinterpret_cast<int*>(reinterpret_cast<ptrdiff_t>(m_buffer->data()) + from.m_offset)[-1] = to.m_offset - from.m_offset;1053 }1054 1055 static void linkAbsoluteAddress(void* code, JmpDst useOffset, JmpDst address)1056 {1057 ASSERT(useOffset.m_offset != -1);1058 ASSERT(address.m_offset != -1);1059 1060 reinterpret_cast<int*>(reinterpret_cast<ptrdiff_t>(code) + useOffset.m_offset)[-1] = reinterpret_cast<ptrdiff_t>(code) + address.m_offset;1061 }1062 1063 static void link(void* code, JmpSrc from, void* to)1064 {1065 ASSERT(from.m_offset != -1);1066 1067 reinterpret_cast<int*>(reinterpret_cast<ptrdiff_t>(code) + from.m_offset)[-1] = reinterpret_cast<ptrdiff_t>(to) - (reinterpret_cast<ptrdiff_t>(code) + from.m_offset);1068 }1069 1070 static void* getRelocatedAddress(void* code, JmpSrc jump)1071 {1072 return reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(code) + jump.m_offset);1073 }1074 1075 static void* getRelocatedAddress(void* code, JmpDst jump)1076 {1077 return reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(code) + jump.m_offset);1078 }1079 1080 static int getDifferenceBetweenLabels(JmpDst src, JmpDst dst)1081 {1082 return dst.m_offset - src.m_offset;1083 }1084 1085 static int getDifferenceBetweenLabels(JmpDst src, JmpSrc dst)1086 {1087 return dst.m_offset - src.m_offset;1088 }1089 1090 static int getDifferenceBetweenLabels(JmpSrc src, JmpDst dst)1091 {1092 return dst.m_offset - src.m_offset;1093 }1094 1095 static void repatchImmediate(intptr_t where, int32_t value)1096 {1097 reinterpret_cast<int32_t*>(where)[-1] = value;1098 }1099 1100 static void repatchDisplacement(intptr_t where, intptr_t value)1101 {1102 reinterpret_cast<intptr_t*>(where)[-1] = value;1103 }1104 1105 static void repatchBranchOffset(intptr_t where, void* destination)1106 {1107 reinterpret_cast<intptr_t*>(where)[-1] = (reinterpret_cast<intptr_t>(destination) - where);1108 }1109 1110 void* executableCopy()1111 {1112 return m_buffer->executableCopy();1113 }1114 1115 #if COMPILER(MSVC)1116 void emitConvertToFastCall()1117 {1118 movl_mr(4, X86::esp, X86::eax);1119 movl_mr(8, X86::esp, X86::edx);1120 movl_mr(12, X86::esp, X86::ecx);1121 }1122 #else1123 void emitConvertToFastCall() {}1124 #endif1125 1126 #if USE(CTI_ARGUMENT)1127 void emitRestoreArgumentReference()1128 {1129 #if USE(FAST_CALL_CTI_ARGUMENT)1130 movl_rr(X86::esp, X86::ecx);1131 #else1132 movl_rm(X86::esp, 0, X86::esp);1133 #endif1134 }1135 1136 void emitRestoreArgumentReferenceForTrampoline()1137 {1138 #if USE(FAST_CALL_CTI_ARGUMENT)1139 movl_rr(X86::esp, X86::ecx);1140 addl_i32r(4, X86::ecx);1141 #endif1142 }1143 #else1144 void emitRestoreArgumentReference() {}1145 void emitRestoreArgumentReferenceForTrampoline() {}1146 #endif1147 1148 private:1149 void emitModRm_rr(RegisterID reg, RegisterID rm)1150 {1151 m_buffer->ensureSpace(maxInstructionSize);1152 emitModRm_rr_Unchecked(reg, rm);1153 }1154 1155 void emitModRm_rr_Unchecked(RegisterID reg, RegisterID rm)1156 {1157 m_buffer->putByteUnchecked(MODRM(3, reg, rm));1158 }1159 1160 void emitModRm_rm(RegisterID reg, void* addr)1161 {1162 m_buffer->putByte(MODRM(0, reg, X86::noBase));1163 m_buffer->putInt((int)addr);1164 }1165 1166 void emitModRm_rm(RegisterID reg, RegisterID base)1167 {1168 if (base == X86::esp) {1169 m_buffer->putByte(MODRM(0, reg, X86::hasSib));1170 m_buffer->putByte(SIB(0, X86::noScale, X86::esp));1171 } else1172 m_buffer->putByte(MODRM(0, reg, base));1173 }1174 1175 void emitModRm_rm_Unchecked(RegisterID reg, RegisterID base, int offset)1176 {1177 if (base == X86::esp) {1178 if (CAN_SIGN_EXTEND_8_32(offset)) {1179 m_buffer->putByteUnchecked(MODRM(1, reg, X86::hasSib));1180 m_buffer->putByteUnchecked(SIB(0, X86::noScale, X86::esp));1181 m_buffer->putByteUnchecked(offset);1182 } else {1183 m_buffer->putByteUnchecked(MODRM(2, reg, X86::hasSib));1184 m_buffer->putByteUnchecked(SIB(0, X86::noScale, X86::esp));1185 m_buffer->putIntUnchecked(offset);1186 }1187 } else {1188 if (CAN_SIGN_EXTEND_8_32(offset)) {1189 m_buffer->putByteUnchecked(MODRM(1, reg, base));1190 m_buffer->putByteUnchecked(offset);1191 } else {1192 m_buffer->putByteUnchecked(MODRM(2, reg, base));1193 m_buffer->putIntUnchecked(offset);1194 }1195 }1196 }1197 1198 void emitModRm_rm(RegisterID reg, RegisterID base, int offset)1199 {1200 m_buffer->ensureSpace(maxInstructionSize);1201 emitModRm_rm_Unchecked(reg, base, offset);1202 }1203 1204 void emitModRm_rmsib(RegisterID reg, RegisterID base, RegisterID index, int scale)1205 {1206 int shift = 0;1207 while (scale >>= 1)1208 shift++;1209 1210 m_buffer->putByte(MODRM(0, reg, X86::hasSib));1211 m_buffer->putByte(SIB(shift, index, base));1212 }1213 1214 void emitModRm_rmsib(RegisterID reg, RegisterID base, RegisterID index, int scale, int offset)1215 {1216 int shift = 0;1217 while (scale >>= 1)1218 shift++;1219 1220 if (CAN_SIGN_EXTEND_8_32(offset)) {1221 m_buffer->putByte(MODRM(1, reg, X86::hasSib));1222 m_buffer->putByte(SIB(shift, index, base));1223 m_buffer->putByte(offset);1224 } else {1225 m_buffer->putByte(MODRM(2, reg, X86::hasSib));1226 m_buffer->putByte(SIB(shift, index, base));1227 m_buffer->putInt(offset);1228 }1229 }1230 1231 void emitModRm_opr(OpcodeID opcodeID, RegisterID rm)1232 {1233 m_buffer->ensureSpace(maxInstructionSize);1234 emitModRm_opr_Unchecked(opcodeID, rm);1235 }1236 1237 void emitModRm_opr_Unchecked(OpcodeID opcodeID, RegisterID rm)1238 {1239 emitModRm_rr_Unchecked(static_cast<RegisterID>(opcodeID), rm);1240 }1241 1242 void emitModRm_opm(OpcodeID opcodeID, RegisterID base)1243 {1244 emitModRm_rm(static_cast<RegisterID>(opcodeID), base);1245 }1246 1247 void emitModRm_opm_Unchecked(OpcodeID opcodeID, RegisterID base, int offset)1248 {1249 emitModRm_rm_Unchecked(static_cast<RegisterID>(opcodeID), base, offset);1250 }1251 1252 void emitModRm_opm(OpcodeID opcodeID, RegisterID base, int offset)1253 {1254 emitModRm_rm(static_cast<RegisterID>(opcodeID), base, offset);1255 }1256 1257 void emitModRm_opm(OpcodeID opcodeID, void* addr)1258 {1259 emitModRm_rm(static_cast<RegisterID>(opcodeID), addr);1260 }1261 1262 void emitModRm_opmsib(OpcodeID opcodeID, RegisterID base, RegisterID index, int scale, int offset)1263 {1264 emitModRm_rmsib(static_cast<RegisterID>(opcodeID), base, index, scale, offset);1265 }1266 1267 AssemblerBuffer* m_buffer;1268 };1269 1270 typedef Vector<X86Assembler::JmpSrc> JmpSrcVector;1271 144 1272 145 } // namespace JSC 1273 146 1274 #endif // ENABLE( MASM) && PLATFORM(X86)147 #endif // ENABLE(ASSEMBLER) 1275 148 1276 #endif // X86Assembler_h149 #endif // AssemblerBuffer_h -
trunk/JavaScriptCore/assembler/X86Assembler.h
r38466 r38487 27 27 #define X86Assembler_h 28 28 29 #if ENABLE(MASM) && PLATFORM(X86) 30 29 #include <wtf/Platform.h> 30 31 #if ENABLE(ASSEMBLER) && PLATFORM(X86) 32 33 #include "AssemblerBuffer.h" 31 34 #include <wtf/Assertions.h> 32 #include <wtf/AlwaysInline.h>33 #include <wtf/FastMalloc.h>34 35 #if HAVE(MMAN)36 #include <sys/mman.h>37 #endif38 39 #include <string.h>40 35 41 36 namespace JSC { 42 43 class AssemblerBuffer {44 public:45 AssemblerBuffer(int capacity)46 : m_buffer(static_cast<char*>(fastMalloc(capacity)))47 , m_capacity(capacity)48 , m_size(0)49 {50 }51 52 ~AssemblerBuffer()53 {54 fastFree(m_buffer);55 }56 57 void ensureSpace(int space)58 {59 if (m_size > m_capacity - space)60 grow();61 }62 63 bool isAligned(int alignment)64 {65 return !(m_size & (alignment - 1));66 }67 68 void putByteUnchecked(int value)69 {70 ASSERT(!(m_size > m_capacity - 4));71 m_buffer[m_size] = value;72 m_size++;73 }74 75 void putByte(int value)76 {77 if (m_size > m_capacity - 4)78 grow();79 putByteUnchecked(value);80 }81 82 void putShortUnchecked(int value)83 {84 ASSERT(!(m_size > m_capacity - 4));85 *reinterpret_cast<short*>(&m_buffer[m_size]) = value;86 m_size += 2;87 }88 89 void putShort(int value)90 {91 if (m_size > m_capacity - 4)92 grow();93 putShortUnchecked(value);94 }95 96 void putIntUnchecked(int value)97 {98 *reinterpret_cast<int*>(&m_buffer[m_size]) = value;99 m_size += 4;100 }101 102 void putInt(int value)103 {104 if (m_size > m_capacity - 4)105 grow();106 putIntUnchecked(value);107 }108 109 void* data()110 {111 return m_buffer;112 }113 114 int size()115 {116 return m_size;117 }118 119 AssemblerBuffer* reset()120 {121 m_size = 0;122 return this;123 }124 125 void* executableCopy()126 {127 if (!m_size)128 return 0;129 130 void* result = WTF::fastMallocExecutable(m_size);131 132 if (!result)133 return 0;134 135 return memcpy(result, m_buffer, m_size);136 }137 138 private:139 void grow()140 {141 m_capacity += m_capacity / 2;142 m_buffer = static_cast<char*>(fastRealloc(m_buffer, m_capacity));143 }144 145 char* m_buffer;146 int m_capacity;147 int m_size;148 };149 37 150 38 #define MODRM(type, reg, rm) ((type << 6) | (reg << 3) | (rm)) … … 1272 1160 } // namespace JSC 1273 1161 1274 #endif // ENABLE( MASM) && PLATFORM(X86)1162 #endif // ENABLE(ASSEMBLER) && PLATFORM(X86) 1275 1163 1276 1164 #endif // X86Assembler_h -
trunk/JavaScriptCore/wtf/Platform.h
r38477 r38487 415 415 416 416 #if ENABLE(JIT) || ENABLE(WREC) 417 #define ENABLE_ MASM1417 #define ENABLE_ASSEMBLER 1 418 418 #endif 419 419
Note:
See TracChangeset
for help on using the changeset viewer.