Changeset 39284 in webkit for trunk/JavaScriptCore/assembler/MacroAssembler.h
- Timestamp:
- Dec 13, 2008, 3:58:58 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/assembler/MacroAssembler.h
r39261 r39284 66 66 } 67 67 68 68 69 // Address: 69 70 // … … 137 138 }; 138 139 140 139 141 class Jump; 142 class RepatchBuffer; 143 144 // DataLabelPtr: 145 // 146 // A DataLabelPtr is used to refer to a location in the code containing a pointer to be 147 // repatched after the code has been generated. 148 class DataLabelPtr { 149 friend class MacroAssembler; 150 151 public: 152 DataLabelPtr() 153 { 154 } 155 156 DataLabelPtr(MacroAssembler* masm) 157 : m_label(masm->m_assembler.label()) 158 { 159 } 160 161 private: 162 X86Assembler::JmpDst m_label; 163 }; 140 164 141 165 // Label: … … 146 170 friend class Jump; 147 171 friend class MacroAssembler; 172 friend class RepatchBuffer; 148 173 149 174 public: … … 160 185 X86Assembler::JmpDst m_label; 161 186 }; 162 187 188 163 189 // Jump: 164 190 // … … 177 203 // Jumps may also be linked to a Label. 178 204 class Jump { 205 friend class RepatchBuffer; 206 friend class MacroAssembler; 207 179 208 public: 180 209 Jump() … … 182 211 } 183 212 213 // FIXME: transitionary method, while we replace JmpSrces with Jumps. 184 214 Jump(X86Assembler::JmpSrc jmp) 185 215 : m_jmp(jmp) … … 242 272 Vector<Jump> m_jumps; 243 273 }; 274 275 276 // RepatchBuffer: 277 // 278 // This class assists in linking code generated by the macro assembler, once code generation 279 // has been completed, and the code has been copied to is final location in memory. At this 280 // time pointers to labels within the code may be resolved, and relative offsets to external 281 // addresses may be fixed. 282 // 283 // Specifically: 284 // * Jump objects may be linked to external targets, 285 // * The address of Jump objects may taken, such that it can later be relinked. 286 // * The return address of a Jump object representing a call may be acquired. 287 // * The address of a Label pointing into the code may be resolved. 288 // * The value referenced by a DataLabel may be fixed. 289 // 290 // FIXME: distinguish between Calls & Jumps (make a specific call to obtain the return 291 // address of calls, as opposed to a point that can be used to later relink a Jump - 292 // possibly wrap the later up in an object that can do just that). 293 class RepatchBuffer { 294 public: 295 RepatchBuffer(void* code) 296 : m_code(code) 297 { 298 } 299 300 void link(Jump jump, void* target) 301 { 302 X86Assembler::link(m_code, jump.m_jmp, target); 303 } 304 305 void* addressOf(Jump jump) 306 { 307 return X86Assembler::getRelocatedAddress(m_code, jump.m_jmp); 308 } 309 310 void* addressOf(Label label) 311 { 312 return X86Assembler::getRelocatedAddress(m_code, label.m_label); 313 } 314 315 void setPtr(DataLabelPtr label, void* value) 316 { 317 X86Assembler::repatchAddress(m_code, label.m_label, value); 318 } 319 320 private: 321 void* m_code; 322 }; 323 244 324 245 325 // Imm32: … … 258 338 }; 259 339 260 261 340 // ImmPtr: 262 341 // … … 281 360 // object). 282 361 283 void addPtr(Imm32 imm, RegisterID dest)362 void addPtr(Imm32 imm, RegisterID srcDest) 284 363 { 285 364 #if PLATFORM(X86_64) 286 365 if (CAN_SIGN_EXTEND_8_32(imm.m_value)) 287 m_assembler.addq_i8r(imm.m_value, dest);288 else 289 m_assembler.addq_i32r(imm.m_value, dest);366 m_assembler.addq_i8r(imm.m_value, srcDest); 367 else 368 m_assembler.addq_i32r(imm.m_value, srcDest); 290 369 #else 291 370 if (CAN_SIGN_EXTEND_8_32(imm.m_value)) 292 m_assembler.addl_i8r(imm.m_value, dest); 293 else 294 m_assembler.addl_i32r(imm.m_value, dest); 295 #endif 371 m_assembler.addl_i8r(imm.m_value, srcDest); 372 else 373 m_assembler.addl_i32r(imm.m_value, srcDest); 374 #endif 375 } 376 377 378 void addPtr(Imm32 imm, RegisterID src, RegisterID dest) 379 { 380 m_assembler.leal_mr(imm.m_value, src, dest); 296 381 } 297 382 … … 335 420 } 336 421 422 void lshift32(RegisterID shift_amount, RegisterID dest) 423 { 424 // On x86 we can only shift by ecx; if asked to shift by another register we'll 425 // need rejig the shift amount into ecx first, and restore the registers afterwards. 426 if (shift_amount != X86::ecx) { 427 m_assembler.xchgl_rr(shift_amount, X86::ecx); 428 429 // E.g. transform "shll %eax, %eax" -> "xchgl %eax, %ecx; shll %ecx, %ecx; xchgl %eax, %ecx" 430 if (dest == shift_amount) 431 m_assembler.shll_CLr(X86::ecx); 432 // E.g. transform "shll %eax, %ecx" -> "xchgl %eax, %ecx; shll %ecx, %eax; xchgl %eax, %ecx" 433 else if (dest == X86::ecx) 434 m_assembler.shll_CLr(shift_amount); 435 // E.g. transform "shll %eax, %ebx" -> "xchgl %eax, %ecx; shll %ecx, %ebx; xchgl %eax, %ecx" 436 else 437 m_assembler.shll_CLr(dest); 438 439 m_assembler.xchgl_rr(shift_amount, X86::ecx); 440 } else 441 m_assembler.shll_CLr(dest); 442 } 443 444 // Take the value from dividend, divide it by divisor, and put the remainder in remainder. 445 // For now, this operation has specific register requirements, and the three register must 446 // be unique. It is unfortunate to expose this in the MacroAssembler interface, however 447 // given the complexity to fix, the fact that it is not uncommmon for processors to have 448 // specific register requirements on this operation (e.g. Mips result in 'hi'), or to not 449 // support a hardware divide at all, it may not be 450 void mod32(RegisterID divisor, RegisterID dividend, RegisterID remainder) 451 { 452 #ifdef NDEBUG 453 #pragma unused(dividend,remainder) 454 #else 455 ASSERT((dividend == X86::eax) && (remainder == X86::edx)); 456 ASSERT((dividend != divisor) && (remainder != divisor)); 457 #endif 458 459 m_assembler.cdq(); 460 m_assembler.idivl_r(divisor); 461 } 462 337 463 void mul32(Imm32 imm, RegisterID src, RegisterID dest) 338 464 { … … 356 482 { 357 483 m_assembler.sarl_i8r(imm.m_value, dest); 484 } 485 486 void rshift32(RegisterID shift_amount, RegisterID dest) 487 { 488 // On x86 we can only shift by ecx; if asked to shift by another register we'll 489 // need rejig the shift amount into ecx first, and restore the registers afterwards. 490 if (shift_amount != X86::ecx) { 491 m_assembler.xchgl_rr(shift_amount, X86::ecx); 492 493 // E.g. transform "shll %eax, %eax" -> "xchgl %eax, %ecx; shll %ecx, %ecx; xchgl %eax, %ecx" 494 if (dest == shift_amount) 495 m_assembler.sarl_CLr(X86::ecx); 496 // E.g. transform "shll %eax, %ecx" -> "xchgl %eax, %ecx; shll %ecx, %eax; xchgl %eax, %ecx" 497 else if (dest == X86::ecx) 498 m_assembler.sarl_CLr(shift_amount); 499 // E.g. transform "shll %eax, %ebx" -> "xchgl %eax, %ecx; shll %ecx, %ebx; xchgl %eax, %ecx" 500 else 501 m_assembler.sarl_CLr(dest); 502 503 m_assembler.xchgl_rr(shift_amount, X86::ecx); 504 } else 505 m_assembler.sarl_CLr(dest); 358 506 } 359 507 … … 478 626 store32(src, address); 479 627 } 480 #endif 481 628 629 DataLabelPtr storePtrWithRepatch(Address address) 630 { 631 if (address.offset) 632 m_assembler.movl_i32m(0, address.offset, address.base); 633 else 634 m_assembler.movl_i32m(0, address.base); 635 return DataLabelPtr(this); 636 } 637 #endif 638 482 639 void store32(RegisterID src, ImplicitAddress address) 483 640 { … … 865 1022 return jnz32(reg, mask); 866 1023 } 1024 1025 Jump jnzPtr(Address address, Imm32 mask = Imm32(-1)) 1026 { 1027 return jnz32(address, mask); 1028 } 867 1029 #endif 868 1030 … … 883 1045 { 884 1046 return jz32(reg, mask); 1047 } 1048 1049 Jump jzPtr(Address address, Imm32 mask = Imm32(-1)) 1050 { 1051 return jz32(address, mask); 885 1052 } 886 1053 … … 980 1147 { 981 1148 m_assembler.link(m_assembler.jmp(), target.m_label); 1149 } 1150 1151 void jump(RegisterID target) 1152 { 1153 m_assembler.jmp_r(target); 1154 } 1155 1156 // Address is a memory location containing the address to jump to 1157 void jump(Address address) 1158 { 1159 if (address.offset) 1160 m_assembler.jmp_m(address.offset, address.base); 1161 else 1162 m_assembler.jmp_m(address.base); 982 1163 } 983 1164 … … 1057 1238 } 1058 1239 1059 void jump(RegisterID target)1060 { 1061 m_assembler.jmp_r(target);1240 Label label() 1241 { 1242 return Label(this); 1062 1243 } 1063 1244
Note:
See TracChangeset
for help on using the changeset viewer.