Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/arm64/assembler-arm64.cc

Issue 318773009: ARM64: Clean up support for explicit literal load. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // 2 //
3 // Redistribution and use in source and binary forms, with or without 3 // Redistribution and use in source and binary forms, with or without
4 // modification, are permitted provided that the following conditions are 4 // modification, are permitted provided that the following conditions are
5 // met: 5 // met:
6 // 6 //
7 // * Redistributions of source code must retain the above copyright 7 // * Redistributions of source code must retain the above copyright
8 // notice, this list of conditions and the following disclaimer. 8 // notice, this list of conditions and the following disclaimer.
9 // * Redistributions in binary form must reproduce the above 9 // * Redistributions in binary form must reproduce the above
10 // copyright notice, this list of conditions and the following 10 // copyright notice, this list of conditions and the following
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 match &= !reg3.IsValid() || reg3.IsSameSizeAndType(reg1); 261 match &= !reg3.IsValid() || reg3.IsSameSizeAndType(reg1);
262 match &= !reg4.IsValid() || reg4.IsSameSizeAndType(reg1); 262 match &= !reg4.IsValid() || reg4.IsSameSizeAndType(reg1);
263 match &= !reg5.IsValid() || reg5.IsSameSizeAndType(reg1); 263 match &= !reg5.IsValid() || reg5.IsSameSizeAndType(reg1);
264 match &= !reg6.IsValid() || reg6.IsSameSizeAndType(reg1); 264 match &= !reg6.IsValid() || reg6.IsSameSizeAndType(reg1);
265 match &= !reg7.IsValid() || reg7.IsSameSizeAndType(reg1); 265 match &= !reg7.IsValid() || reg7.IsSameSizeAndType(reg1);
266 match &= !reg8.IsValid() || reg8.IsSameSizeAndType(reg1); 266 match &= !reg8.IsValid() || reg8.IsSameSizeAndType(reg1);
267 return match; 267 return match;
268 } 268 }
269 269
270 270
271 void Operand::initialize_handle(Handle<Object> handle) { 271 void Immediate::InitializeHandle(Handle<Object> handle) {
272 AllowDeferredHandleDereference using_raw_address; 272 AllowDeferredHandleDereference using_raw_address;
273 273
274 // Verify all Objects referred by code are NOT in new space. 274 // Verify all Objects referred by code are NOT in new space.
275 Object* obj = *handle; 275 Object* obj = *handle;
276 if (obj->IsHeapObject()) { 276 if (obj->IsHeapObject()) {
277 ASSERT(!HeapObject::cast(obj)->GetHeap()->InNewSpace(obj)); 277 ASSERT(!HeapObject::cast(obj)->GetHeap()->InNewSpace(obj));
278 immediate_ = reinterpret_cast<intptr_t>(handle.location()); 278 value_ = reinterpret_cast<intptr_t>(handle.location());
279 rmode_ = RelocInfo::EMBEDDED_OBJECT; 279 rmode_ = RelocInfo::EMBEDDED_OBJECT;
280 } else { 280 } else {
281 STATIC_ASSERT(sizeof(intptr_t) == sizeof(int64_t)); 281 STATIC_ASSERT(sizeof(intptr_t) == sizeof(int64_t));
282 immediate_ = reinterpret_cast<intptr_t>(obj); 282 value_ = reinterpret_cast<intptr_t>(obj);
283 rmode_ = RelocInfo::NONE64; 283 rmode_ = RelocInfo::NONE64;
284 } 284 }
285 } 285 }
286 286
287 287
288 bool Operand::NeedsRelocation(const Assembler* assembler) const { 288 bool Operand::NeedsRelocation(const Assembler* assembler) const {
289 if (rmode_ == RelocInfo::EXTERNAL_REFERENCE) { 289 RelocInfo::Mode rmode = immediate_.rmode();
290
291 if (rmode == RelocInfo::EXTERNAL_REFERENCE) {
290 return assembler->serializer_enabled(); 292 return assembler->serializer_enabled();
291 } 293 }
292 294
293 return !RelocInfo::IsNone(rmode_); 295 return !RelocInfo::IsNone(rmode);
294 } 296 }
295 297
296 298
297 // Assembler 299 // Assembler
298 300
299 Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size) 301 Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size)
300 : AssemblerBase(isolate, buffer, buffer_size), 302 : AssemblerBase(isolate, buffer, buffer_size),
301 recorded_ast_id_(TypeFeedbackId::None()), 303 recorded_ast_id_(TypeFeedbackId::None()),
302 unresolved_branches_(), 304 unresolved_branches_(),
303 positions_recorder_(this) { 305 positions_recorder_(this) {
(...skipping 1162 matching lines...) Expand 10 before | Expand all | Expand 10 after
1466 LoadStore(rt, src, StoreOpFor(rt)); 1468 LoadStore(rt, src, StoreOpFor(rt));
1467 } 1469 }
1468 1470
1469 1471
1470 void Assembler::ldrsw(const Register& rt, const MemOperand& src) { 1472 void Assembler::ldrsw(const Register& rt, const MemOperand& src) {
1471 ASSERT(rt.Is64Bits()); 1473 ASSERT(rt.Is64Bits());
1472 LoadStore(rt, src, LDRSW_x); 1474 LoadStore(rt, src, LDRSW_x);
1473 } 1475 }
1474 1476
1475 1477
1476 void Assembler::ldr(const Register& rt, uint64_t imm) { 1478 void Assembler::ldr_pcrel(const CPURegister& rt, int imm19) {
1477 // TODO(all): Constant pool may be garbage collected. Hence we cannot store 1479 // The pattern 'ldr xzr, #offset' is used to indicate the beginning of a
1478 // arbitrary values in them. Manually move it for now. Fix 1480 // constant pool. It should not be emitted.
1479 // MacroAssembler::Fmov when this is implemented. 1481 ASSERT(!rt.IsZero());
1480 UNIMPLEMENTED(); 1482 Emit(LoadLiteralOpFor(rt) | ImmLLiteral(imm19) | Rt(rt));
rmcilroy 2014/06/06 22:48:58 How about having the argument be a byte offset fro
Rodolph Perfetta (ARM) 2014/06/09 14:12:21 It is more natural I agree but up to now at the as
rmcilroy 2014/06/09 14:22:10 I prefer that it stays consistent with what's alre
1481 } 1483 }
1482 1484
1483 1485
1484 void Assembler::ldr(const FPRegister& ft, double imm) { 1486 void Assembler::ldr(const CPURegister& rt, const Immediate& imm) {
1485 // TODO(all): Constant pool may be garbage collected. Hence we cannot store 1487 // Currently we only support 64-bit literals.
1486 // arbitrary values in them. Manually move it for now. Fix 1488 ASSERT(rt.Is64Bits());
1487 // MacroAssembler::Fmov when this is implemented. 1489
1488 UNIMPLEMENTED(); 1490 RecordRelocInfo(imm.rmode(), imm.value());
1491 BlockConstPoolFor(1);
1492 // The load will be patched when the constpool is emitted, patching code
1493 // expect a load literal with offset 0.
1494 ldr_pcrel(rt, 0);
1489 } 1495 }
1490 1496
1491 1497
1492 void Assembler::ldr(const FPRegister& ft, float imm) {
1493 // TODO(all): Constant pool may be garbage collected. Hence we cannot store
1494 // arbitrary values in them. Manually move it for now. Fix
1495 // MacroAssembler::Fmov when this is implemented.
1496 UNIMPLEMENTED();
1497 }
1498
1499
1500 void Assembler::mov(const Register& rd, const Register& rm) { 1498 void Assembler::mov(const Register& rd, const Register& rm) {
1501 // Moves involving the stack pointer are encoded as add immediate with 1499 // Moves involving the stack pointer are encoded as add immediate with
1502 // second operand of zero. Otherwise, orr with first operand zr is 1500 // second operand of zero. Otherwise, orr with first operand zr is
1503 // used. 1501 // used.
1504 if (rd.IsSP() || rm.IsSP()) { 1502 if (rd.IsSP() || rm.IsSP()) {
1505 add(rd, rm, 0); 1503 add(rd, rm, 0);
1506 } else { 1504 } else {
1507 orr(rd, AppropriateZeroRegFor(rd), rm); 1505 orr(rd, AppropriateZeroRegFor(rd), rm);
1508 } 1506 }
1509 } 1507 }
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after
1912 1910
1913 1911
1914 void Assembler::AddSub(const Register& rd, 1912 void Assembler::AddSub(const Register& rd,
1915 const Register& rn, 1913 const Register& rn,
1916 const Operand& operand, 1914 const Operand& operand,
1917 FlagsUpdate S, 1915 FlagsUpdate S,
1918 AddSubOp op) { 1916 AddSubOp op) {
1919 ASSERT(rd.SizeInBits() == rn.SizeInBits()); 1917 ASSERT(rd.SizeInBits() == rn.SizeInBits());
1920 ASSERT(!operand.NeedsRelocation(this)); 1918 ASSERT(!operand.NeedsRelocation(this));
1921 if (operand.IsImmediate()) { 1919 if (operand.IsImmediate()) {
1922 int64_t immediate = operand.immediate(); 1920 int64_t immediate = operand.ImmediateValue();
1923 ASSERT(IsImmAddSub(immediate)); 1921 ASSERT(IsImmAddSub(immediate));
1924 Instr dest_reg = (S == SetFlags) ? Rd(rd) : RdSP(rd); 1922 Instr dest_reg = (S == SetFlags) ? Rd(rd) : RdSP(rd);
1925 Emit(SF(rd) | AddSubImmediateFixed | op | Flags(S) | 1923 Emit(SF(rd) | AddSubImmediateFixed | op | Flags(S) |
1926 ImmAddSub(immediate) | dest_reg | RnSP(rn)); 1924 ImmAddSub(immediate) | dest_reg | RnSP(rn));
1927 } else if (operand.IsShiftedRegister()) { 1925 } else if (operand.IsShiftedRegister()) {
1928 ASSERT(operand.reg().SizeInBits() == rd.SizeInBits()); 1926 ASSERT(operand.reg().SizeInBits() == rd.SizeInBits());
1929 ASSERT(operand.shift() != ROR); 1927 ASSERT(operand.shift() != ROR);
1930 1928
1931 // For instructions of the form: 1929 // For instructions of the form:
1932 // add/sub wsp, <Wn>, <Wm> [, LSL #0-3 ] 1930 // add/sub wsp, <Wn>, <Wm> [, LSL #0-3 ]
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
2008 } 2006 }
2009 2007
2010 2008
2011 void Assembler::Logical(const Register& rd, 2009 void Assembler::Logical(const Register& rd,
2012 const Register& rn, 2010 const Register& rn,
2013 const Operand& operand, 2011 const Operand& operand,
2014 LogicalOp op) { 2012 LogicalOp op) {
2015 ASSERT(rd.SizeInBits() == rn.SizeInBits()); 2013 ASSERT(rd.SizeInBits() == rn.SizeInBits());
2016 ASSERT(!operand.NeedsRelocation(this)); 2014 ASSERT(!operand.NeedsRelocation(this));
2017 if (operand.IsImmediate()) { 2015 if (operand.IsImmediate()) {
2018 int64_t immediate = operand.immediate(); 2016 int64_t immediate = operand.ImmediateValue();
2019 unsigned reg_size = rd.SizeInBits(); 2017 unsigned reg_size = rd.SizeInBits();
2020 2018
2021 ASSERT(immediate != 0); 2019 ASSERT(immediate != 0);
2022 ASSERT(immediate != -1); 2020 ASSERT(immediate != -1);
2023 ASSERT(rd.Is64Bits() || is_uint32(immediate)); 2021 ASSERT(rd.Is64Bits() || is_uint32(immediate));
2024 2022
2025 // If the operation is NOT, invert the operation and immediate. 2023 // If the operation is NOT, invert the operation and immediate.
2026 if ((op & NOT) == NOT) { 2024 if ((op & NOT) == NOT) {
2027 op = static_cast<LogicalOp>(op & ~NOT); 2025 op = static_cast<LogicalOp>(op & ~NOT);
2028 immediate = rd.Is64Bits() ? ~immediate : (~immediate & kWRegMask); 2026 immediate = rd.Is64Bits() ? ~immediate : (~immediate & kWRegMask);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2060 2058
2061 2059
2062 void Assembler::ConditionalCompare(const Register& rn, 2060 void Assembler::ConditionalCompare(const Register& rn,
2063 const Operand& operand, 2061 const Operand& operand,
2064 StatusFlags nzcv, 2062 StatusFlags nzcv,
2065 Condition cond, 2063 Condition cond,
2066 ConditionalCompareOp op) { 2064 ConditionalCompareOp op) {
2067 Instr ccmpop; 2065 Instr ccmpop;
2068 ASSERT(!operand.NeedsRelocation(this)); 2066 ASSERT(!operand.NeedsRelocation(this));
2069 if (operand.IsImmediate()) { 2067 if (operand.IsImmediate()) {
2070 int64_t immediate = operand.immediate(); 2068 int64_t immediate = operand.ImmediateValue();
2071 ASSERT(IsImmConditionalCompare(immediate)); 2069 ASSERT(IsImmConditionalCompare(immediate));
2072 ccmpop = ConditionalCompareImmediateFixed | op | ImmCondCmp(immediate); 2070 ccmpop = ConditionalCompareImmediateFixed | op | ImmCondCmp(immediate);
2073 } else { 2071 } else {
2074 ASSERT(operand.IsShiftedRegister() && (operand.shift_amount() == 0)); 2072 ASSERT(operand.IsShiftedRegister() && (operand.shift_amount() == 0));
2075 ccmpop = ConditionalCompareRegisterFixed | op | Rm(operand.reg()); 2073 ccmpop = ConditionalCompareRegisterFixed | op | Rm(operand.reg());
2076 } 2074 }
2077 Emit(SF(rn) | ccmpop | Cond(cond) | Rn(rn) | Nzcv(nzcv)); 2075 Emit(SF(rn) | ccmpop | Cond(cond) | Rn(rn) | Nzcv(nzcv));
2078 } 2076 }
2079 2077
2080 2078
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
2262 return is_int9(offset); 2260 return is_int9(offset);
2263 } 2261 }
2264 2262
2265 2263
2266 bool Assembler::IsImmLSScaled(ptrdiff_t offset, LSDataSize size) { 2264 bool Assembler::IsImmLSScaled(ptrdiff_t offset, LSDataSize size) {
2267 bool offset_is_size_multiple = (((offset >> size) << size) == offset); 2265 bool offset_is_size_multiple = (((offset >> size) << size) == offset);
2268 return offset_is_size_multiple && is_uint12(offset >> size); 2266 return offset_is_size_multiple && is_uint12(offset >> size);
2269 } 2267 }
2270 2268
2271 2269
2272 void Assembler::LoadLiteral(const CPURegister& rt, int offset_from_pc) {
2273 ASSERT((offset_from_pc & ((1 << kLiteralEntrySizeLog2) - 1)) == 0);
2274 // The pattern 'ldr xzr, #offset' is used to indicate the beginning of a
2275 // constant pool. It should not be emitted.
2276 ASSERT(!rt.Is(xzr));
2277 Emit(LDR_x_lit |
2278 ImmLLiteral(offset_from_pc >> kLiteralEntrySizeLog2) |
2279 Rt(rt));
2280 }
2281
2282
2283 void Assembler::LoadRelocatedValue(const CPURegister& rt,
2284 const Operand& operand,
2285 LoadLiteralOp op) {
2286 int64_t imm = operand.immediate();
2287 ASSERT(is_int32(imm) || is_uint32(imm) || (rt.Is64Bits()));
2288 RecordRelocInfo(operand.rmode(), imm);
2289 BlockConstPoolFor(1);
2290 Emit(op | ImmLLiteral(0) | Rt(rt));
2291 }
2292
2293
2294 // Test if a given value can be encoded in the immediate field of a logical 2270 // Test if a given value can be encoded in the immediate field of a logical
2295 // instruction. 2271 // instruction.
2296 // If it can be encoded, the function returns true, and values pointed to by n, 2272 // If it can be encoded, the function returns true, and values pointed to by n,
2297 // imm_s and imm_r are updated with immediates encoded in the format required 2273 // imm_s and imm_r are updated with immediates encoded in the format required
2298 // by the corresponding fields in the logical instruction. 2274 // by the corresponding fields in the logical instruction.
2299 // If it can not be encoded, the function returns false, and the values pointed 2275 // If it can not be encoded, the function returns false, and the values pointed
2300 // to by n, imm_s and imm_r are undefined. 2276 // to by n, imm_s and imm_r are undefined.
2301 bool Assembler::IsImmLogical(uint64_t value, 2277 bool Assembler::IsImmLogical(uint64_t value,
2302 unsigned width, 2278 unsigned width,
2303 unsigned* n, 2279 unsigned* n,
(...skipping 603 matching lines...) Expand 10 before | Expand all | Expand 10 after
2907 adr(rd, 0); 2883 adr(rd, 0);
2908 MovInt64(scratch, target_offset); 2884 MovInt64(scratch, target_offset);
2909 add(rd, rd, scratch); 2885 add(rd, rd, scratch);
2910 } 2886 }
2911 } 2887 }
2912 2888
2913 2889
2914 } } // namespace v8::internal 2890 } } // namespace v8::internal
2915 2891
2916 #endif // V8_TARGET_ARCH_ARM64 2892 #endif // V8_TARGET_ARCH_ARM64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698