| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef V8_ARM64_MACRO_ASSEMBLER_ARM64_INL_H_ | 5 #ifndef V8_ARM64_MACRO_ASSEMBLER_ARM64_INL_H_ |
| 6 #define V8_ARM64_MACRO_ASSEMBLER_ARM64_INL_H_ | 6 #define V8_ARM64_MACRO_ASSEMBLER_ARM64_INL_H_ |
| 7 | 7 |
| 8 #include <ctype.h> | 8 #include <ctype.h> |
| 9 | 9 |
| 10 #include "src/globals.h" | 10 #include "src/globals.h" |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 | 30 |
| 31 | 31 |
| 32 MemOperand UntagSmiMemOperand(Register object, int offset) { | 32 MemOperand UntagSmiMemOperand(Register object, int offset) { |
| 33 // Assumes that Smis are shifted by 32 bits and little endianness. | 33 // Assumes that Smis are shifted by 32 bits and little endianness. |
| 34 STATIC_ASSERT(kSmiShift == 32); | 34 STATIC_ASSERT(kSmiShift == 32); |
| 35 return MemOperand(object, offset + (kSmiShift / kBitsPerByte)); | 35 return MemOperand(object, offset + (kSmiShift / kBitsPerByte)); |
| 36 } | 36 } |
| 37 | 37 |
| 38 | 38 |
| 39 Handle<Object> MacroAssembler::CodeObject() { | 39 Handle<Object> MacroAssembler::CodeObject() { |
| 40 ASSERT(!code_object_.is_null()); | 40 DCHECK(!code_object_.is_null()); |
| 41 return code_object_; | 41 return code_object_; |
| 42 } | 42 } |
| 43 | 43 |
| 44 | 44 |
| 45 void MacroAssembler::And(const Register& rd, | 45 void MacroAssembler::And(const Register& rd, |
| 46 const Register& rn, | 46 const Register& rn, |
| 47 const Operand& operand) { | 47 const Operand& operand) { |
| 48 ASSERT(allow_macro_instructions_); | 48 DCHECK(allow_macro_instructions_); |
| 49 ASSERT(!rd.IsZero()); | 49 DCHECK(!rd.IsZero()); |
| 50 LogicalMacro(rd, rn, operand, AND); | 50 LogicalMacro(rd, rn, operand, AND); |
| 51 } | 51 } |
| 52 | 52 |
| 53 | 53 |
| 54 void MacroAssembler::Ands(const Register& rd, | 54 void MacroAssembler::Ands(const Register& rd, |
| 55 const Register& rn, | 55 const Register& rn, |
| 56 const Operand& operand) { | 56 const Operand& operand) { |
| 57 ASSERT(allow_macro_instructions_); | 57 DCHECK(allow_macro_instructions_); |
| 58 ASSERT(!rd.IsZero()); | 58 DCHECK(!rd.IsZero()); |
| 59 LogicalMacro(rd, rn, operand, ANDS); | 59 LogicalMacro(rd, rn, operand, ANDS); |
| 60 } | 60 } |
| 61 | 61 |
| 62 | 62 |
| 63 void MacroAssembler::Tst(const Register& rn, | 63 void MacroAssembler::Tst(const Register& rn, |
| 64 const Operand& operand) { | 64 const Operand& operand) { |
| 65 ASSERT(allow_macro_instructions_); | 65 DCHECK(allow_macro_instructions_); |
| 66 LogicalMacro(AppropriateZeroRegFor(rn), rn, operand, ANDS); | 66 LogicalMacro(AppropriateZeroRegFor(rn), rn, operand, ANDS); |
| 67 } | 67 } |
| 68 | 68 |
| 69 | 69 |
| 70 void MacroAssembler::Bic(const Register& rd, | 70 void MacroAssembler::Bic(const Register& rd, |
| 71 const Register& rn, | 71 const Register& rn, |
| 72 const Operand& operand) { | 72 const Operand& operand) { |
| 73 ASSERT(allow_macro_instructions_); | 73 DCHECK(allow_macro_instructions_); |
| 74 ASSERT(!rd.IsZero()); | 74 DCHECK(!rd.IsZero()); |
| 75 LogicalMacro(rd, rn, operand, BIC); | 75 LogicalMacro(rd, rn, operand, BIC); |
| 76 } | 76 } |
| 77 | 77 |
| 78 | 78 |
| 79 void MacroAssembler::Bics(const Register& rd, | 79 void MacroAssembler::Bics(const Register& rd, |
| 80 const Register& rn, | 80 const Register& rn, |
| 81 const Operand& operand) { | 81 const Operand& operand) { |
| 82 ASSERT(allow_macro_instructions_); | 82 DCHECK(allow_macro_instructions_); |
| 83 ASSERT(!rd.IsZero()); | 83 DCHECK(!rd.IsZero()); |
| 84 LogicalMacro(rd, rn, operand, BICS); | 84 LogicalMacro(rd, rn, operand, BICS); |
| 85 } | 85 } |
| 86 | 86 |
| 87 | 87 |
| 88 void MacroAssembler::Orr(const Register& rd, | 88 void MacroAssembler::Orr(const Register& rd, |
| 89 const Register& rn, | 89 const Register& rn, |
| 90 const Operand& operand) { | 90 const Operand& operand) { |
| 91 ASSERT(allow_macro_instructions_); | 91 DCHECK(allow_macro_instructions_); |
| 92 ASSERT(!rd.IsZero()); | 92 DCHECK(!rd.IsZero()); |
| 93 LogicalMacro(rd, rn, operand, ORR); | 93 LogicalMacro(rd, rn, operand, ORR); |
| 94 } | 94 } |
| 95 | 95 |
| 96 | 96 |
| 97 void MacroAssembler::Orn(const Register& rd, | 97 void MacroAssembler::Orn(const Register& rd, |
| 98 const Register& rn, | 98 const Register& rn, |
| 99 const Operand& operand) { | 99 const Operand& operand) { |
| 100 ASSERT(allow_macro_instructions_); | 100 DCHECK(allow_macro_instructions_); |
| 101 ASSERT(!rd.IsZero()); | 101 DCHECK(!rd.IsZero()); |
| 102 LogicalMacro(rd, rn, operand, ORN); | 102 LogicalMacro(rd, rn, operand, ORN); |
| 103 } | 103 } |
| 104 | 104 |
| 105 | 105 |
| 106 void MacroAssembler::Eor(const Register& rd, | 106 void MacroAssembler::Eor(const Register& rd, |
| 107 const Register& rn, | 107 const Register& rn, |
| 108 const Operand& operand) { | 108 const Operand& operand) { |
| 109 ASSERT(allow_macro_instructions_); | 109 DCHECK(allow_macro_instructions_); |
| 110 ASSERT(!rd.IsZero()); | 110 DCHECK(!rd.IsZero()); |
| 111 LogicalMacro(rd, rn, operand, EOR); | 111 LogicalMacro(rd, rn, operand, EOR); |
| 112 } | 112 } |
| 113 | 113 |
| 114 | 114 |
| 115 void MacroAssembler::Eon(const Register& rd, | 115 void MacroAssembler::Eon(const Register& rd, |
| 116 const Register& rn, | 116 const Register& rn, |
| 117 const Operand& operand) { | 117 const Operand& operand) { |
| 118 ASSERT(allow_macro_instructions_); | 118 DCHECK(allow_macro_instructions_); |
| 119 ASSERT(!rd.IsZero()); | 119 DCHECK(!rd.IsZero()); |
| 120 LogicalMacro(rd, rn, operand, EON); | 120 LogicalMacro(rd, rn, operand, EON); |
| 121 } | 121 } |
| 122 | 122 |
| 123 | 123 |
| 124 void MacroAssembler::Ccmp(const Register& rn, | 124 void MacroAssembler::Ccmp(const Register& rn, |
| 125 const Operand& operand, | 125 const Operand& operand, |
| 126 StatusFlags nzcv, | 126 StatusFlags nzcv, |
| 127 Condition cond) { | 127 Condition cond) { |
| 128 ASSERT(allow_macro_instructions_); | 128 DCHECK(allow_macro_instructions_); |
| 129 if (operand.IsImmediate() && (operand.ImmediateValue() < 0)) { | 129 if (operand.IsImmediate() && (operand.ImmediateValue() < 0)) { |
| 130 ConditionalCompareMacro(rn, -operand.ImmediateValue(), nzcv, cond, CCMN); | 130 ConditionalCompareMacro(rn, -operand.ImmediateValue(), nzcv, cond, CCMN); |
| 131 } else { | 131 } else { |
| 132 ConditionalCompareMacro(rn, operand, nzcv, cond, CCMP); | 132 ConditionalCompareMacro(rn, operand, nzcv, cond, CCMP); |
| 133 } | 133 } |
| 134 } | 134 } |
| 135 | 135 |
| 136 | 136 |
| 137 void MacroAssembler::Ccmn(const Register& rn, | 137 void MacroAssembler::Ccmn(const Register& rn, |
| 138 const Operand& operand, | 138 const Operand& operand, |
| 139 StatusFlags nzcv, | 139 StatusFlags nzcv, |
| 140 Condition cond) { | 140 Condition cond) { |
| 141 ASSERT(allow_macro_instructions_); | 141 DCHECK(allow_macro_instructions_); |
| 142 if (operand.IsImmediate() && (operand.ImmediateValue() < 0)) { | 142 if (operand.IsImmediate() && (operand.ImmediateValue() < 0)) { |
| 143 ConditionalCompareMacro(rn, -operand.ImmediateValue(), nzcv, cond, CCMP); | 143 ConditionalCompareMacro(rn, -operand.ImmediateValue(), nzcv, cond, CCMP); |
| 144 } else { | 144 } else { |
| 145 ConditionalCompareMacro(rn, operand, nzcv, cond, CCMN); | 145 ConditionalCompareMacro(rn, operand, nzcv, cond, CCMN); |
| 146 } | 146 } |
| 147 } | 147 } |
| 148 | 148 |
| 149 | 149 |
| 150 void MacroAssembler::Add(const Register& rd, | 150 void MacroAssembler::Add(const Register& rd, |
| 151 const Register& rn, | 151 const Register& rn, |
| 152 const Operand& operand) { | 152 const Operand& operand) { |
| 153 ASSERT(allow_macro_instructions_); | 153 DCHECK(allow_macro_instructions_); |
| 154 if (operand.IsImmediate() && (operand.ImmediateValue() < 0) && | 154 if (operand.IsImmediate() && (operand.ImmediateValue() < 0) && |
| 155 IsImmAddSub(-operand.ImmediateValue())) { | 155 IsImmAddSub(-operand.ImmediateValue())) { |
| 156 AddSubMacro(rd, rn, -operand.ImmediateValue(), LeaveFlags, SUB); | 156 AddSubMacro(rd, rn, -operand.ImmediateValue(), LeaveFlags, SUB); |
| 157 } else { | 157 } else { |
| 158 AddSubMacro(rd, rn, operand, LeaveFlags, ADD); | 158 AddSubMacro(rd, rn, operand, LeaveFlags, ADD); |
| 159 } | 159 } |
| 160 } | 160 } |
| 161 | 161 |
| 162 void MacroAssembler::Adds(const Register& rd, | 162 void MacroAssembler::Adds(const Register& rd, |
| 163 const Register& rn, | 163 const Register& rn, |
| 164 const Operand& operand) { | 164 const Operand& operand) { |
| 165 ASSERT(allow_macro_instructions_); | 165 DCHECK(allow_macro_instructions_); |
| 166 if (operand.IsImmediate() && (operand.ImmediateValue() < 0) && | 166 if (operand.IsImmediate() && (operand.ImmediateValue() < 0) && |
| 167 IsImmAddSub(-operand.ImmediateValue())) { | 167 IsImmAddSub(-operand.ImmediateValue())) { |
| 168 AddSubMacro(rd, rn, -operand.ImmediateValue(), SetFlags, SUB); | 168 AddSubMacro(rd, rn, -operand.ImmediateValue(), SetFlags, SUB); |
| 169 } else { | 169 } else { |
| 170 AddSubMacro(rd, rn, operand, SetFlags, ADD); | 170 AddSubMacro(rd, rn, operand, SetFlags, ADD); |
| 171 } | 171 } |
| 172 } | 172 } |
| 173 | 173 |
| 174 | 174 |
| 175 void MacroAssembler::Sub(const Register& rd, | 175 void MacroAssembler::Sub(const Register& rd, |
| 176 const Register& rn, | 176 const Register& rn, |
| 177 const Operand& operand) { | 177 const Operand& operand) { |
| 178 ASSERT(allow_macro_instructions_); | 178 DCHECK(allow_macro_instructions_); |
| 179 if (operand.IsImmediate() && (operand.ImmediateValue() < 0) && | 179 if (operand.IsImmediate() && (operand.ImmediateValue() < 0) && |
| 180 IsImmAddSub(-operand.ImmediateValue())) { | 180 IsImmAddSub(-operand.ImmediateValue())) { |
| 181 AddSubMacro(rd, rn, -operand.ImmediateValue(), LeaveFlags, ADD); | 181 AddSubMacro(rd, rn, -operand.ImmediateValue(), LeaveFlags, ADD); |
| 182 } else { | 182 } else { |
| 183 AddSubMacro(rd, rn, operand, LeaveFlags, SUB); | 183 AddSubMacro(rd, rn, operand, LeaveFlags, SUB); |
| 184 } | 184 } |
| 185 } | 185 } |
| 186 | 186 |
| 187 | 187 |
| 188 void MacroAssembler::Subs(const Register& rd, | 188 void MacroAssembler::Subs(const Register& rd, |
| 189 const Register& rn, | 189 const Register& rn, |
| 190 const Operand& operand) { | 190 const Operand& operand) { |
| 191 ASSERT(allow_macro_instructions_); | 191 DCHECK(allow_macro_instructions_); |
| 192 if (operand.IsImmediate() && (operand.ImmediateValue() < 0) && | 192 if (operand.IsImmediate() && (operand.ImmediateValue() < 0) && |
| 193 IsImmAddSub(-operand.ImmediateValue())) { | 193 IsImmAddSub(-operand.ImmediateValue())) { |
| 194 AddSubMacro(rd, rn, -operand.ImmediateValue(), SetFlags, ADD); | 194 AddSubMacro(rd, rn, -operand.ImmediateValue(), SetFlags, ADD); |
| 195 } else { | 195 } else { |
| 196 AddSubMacro(rd, rn, operand, SetFlags, SUB); | 196 AddSubMacro(rd, rn, operand, SetFlags, SUB); |
| 197 } | 197 } |
| 198 } | 198 } |
| 199 | 199 |
| 200 | 200 |
| 201 void MacroAssembler::Cmn(const Register& rn, const Operand& operand) { | 201 void MacroAssembler::Cmn(const Register& rn, const Operand& operand) { |
| 202 ASSERT(allow_macro_instructions_); | 202 DCHECK(allow_macro_instructions_); |
| 203 Adds(AppropriateZeroRegFor(rn), rn, operand); | 203 Adds(AppropriateZeroRegFor(rn), rn, operand); |
| 204 } | 204 } |
| 205 | 205 |
| 206 | 206 |
| 207 void MacroAssembler::Cmp(const Register& rn, const Operand& operand) { | 207 void MacroAssembler::Cmp(const Register& rn, const Operand& operand) { |
| 208 ASSERT(allow_macro_instructions_); | 208 DCHECK(allow_macro_instructions_); |
| 209 Subs(AppropriateZeroRegFor(rn), rn, operand); | 209 Subs(AppropriateZeroRegFor(rn), rn, operand); |
| 210 } | 210 } |
| 211 | 211 |
| 212 | 212 |
| 213 void MacroAssembler::Neg(const Register& rd, | 213 void MacroAssembler::Neg(const Register& rd, |
| 214 const Operand& operand) { | 214 const Operand& operand) { |
| 215 ASSERT(allow_macro_instructions_); | 215 DCHECK(allow_macro_instructions_); |
| 216 ASSERT(!rd.IsZero()); | 216 DCHECK(!rd.IsZero()); |
| 217 if (operand.IsImmediate()) { | 217 if (operand.IsImmediate()) { |
| 218 Mov(rd, -operand.ImmediateValue()); | 218 Mov(rd, -operand.ImmediateValue()); |
| 219 } else { | 219 } else { |
| 220 Sub(rd, AppropriateZeroRegFor(rd), operand); | 220 Sub(rd, AppropriateZeroRegFor(rd), operand); |
| 221 } | 221 } |
| 222 } | 222 } |
| 223 | 223 |
| 224 | 224 |
| 225 void MacroAssembler::Negs(const Register& rd, | 225 void MacroAssembler::Negs(const Register& rd, |
| 226 const Operand& operand) { | 226 const Operand& operand) { |
| 227 ASSERT(allow_macro_instructions_); | 227 DCHECK(allow_macro_instructions_); |
| 228 Subs(rd, AppropriateZeroRegFor(rd), operand); | 228 Subs(rd, AppropriateZeroRegFor(rd), operand); |
| 229 } | 229 } |
| 230 | 230 |
| 231 | 231 |
| 232 void MacroAssembler::Adc(const Register& rd, | 232 void MacroAssembler::Adc(const Register& rd, |
| 233 const Register& rn, | 233 const Register& rn, |
| 234 const Operand& operand) { | 234 const Operand& operand) { |
| 235 ASSERT(allow_macro_instructions_); | 235 DCHECK(allow_macro_instructions_); |
| 236 ASSERT(!rd.IsZero()); | 236 DCHECK(!rd.IsZero()); |
| 237 AddSubWithCarryMacro(rd, rn, operand, LeaveFlags, ADC); | 237 AddSubWithCarryMacro(rd, rn, operand, LeaveFlags, ADC); |
| 238 } | 238 } |
| 239 | 239 |
| 240 | 240 |
| 241 void MacroAssembler::Adcs(const Register& rd, | 241 void MacroAssembler::Adcs(const Register& rd, |
| 242 const Register& rn, | 242 const Register& rn, |
| 243 const Operand& operand) { | 243 const Operand& operand) { |
| 244 ASSERT(allow_macro_instructions_); | 244 DCHECK(allow_macro_instructions_); |
| 245 ASSERT(!rd.IsZero()); | 245 DCHECK(!rd.IsZero()); |
| 246 AddSubWithCarryMacro(rd, rn, operand, SetFlags, ADC); | 246 AddSubWithCarryMacro(rd, rn, operand, SetFlags, ADC); |
| 247 } | 247 } |
| 248 | 248 |
| 249 | 249 |
| 250 void MacroAssembler::Sbc(const Register& rd, | 250 void MacroAssembler::Sbc(const Register& rd, |
| 251 const Register& rn, | 251 const Register& rn, |
| 252 const Operand& operand) { | 252 const Operand& operand) { |
| 253 ASSERT(allow_macro_instructions_); | 253 DCHECK(allow_macro_instructions_); |
| 254 ASSERT(!rd.IsZero()); | 254 DCHECK(!rd.IsZero()); |
| 255 AddSubWithCarryMacro(rd, rn, operand, LeaveFlags, SBC); | 255 AddSubWithCarryMacro(rd, rn, operand, LeaveFlags, SBC); |
| 256 } | 256 } |
| 257 | 257 |
| 258 | 258 |
| 259 void MacroAssembler::Sbcs(const Register& rd, | 259 void MacroAssembler::Sbcs(const Register& rd, |
| 260 const Register& rn, | 260 const Register& rn, |
| 261 const Operand& operand) { | 261 const Operand& operand) { |
| 262 ASSERT(allow_macro_instructions_); | 262 DCHECK(allow_macro_instructions_); |
| 263 ASSERT(!rd.IsZero()); | 263 DCHECK(!rd.IsZero()); |
| 264 AddSubWithCarryMacro(rd, rn, operand, SetFlags, SBC); | 264 AddSubWithCarryMacro(rd, rn, operand, SetFlags, SBC); |
| 265 } | 265 } |
| 266 | 266 |
| 267 | 267 |
| 268 void MacroAssembler::Ngc(const Register& rd, | 268 void MacroAssembler::Ngc(const Register& rd, |
| 269 const Operand& operand) { | 269 const Operand& operand) { |
| 270 ASSERT(allow_macro_instructions_); | 270 DCHECK(allow_macro_instructions_); |
| 271 ASSERT(!rd.IsZero()); | 271 DCHECK(!rd.IsZero()); |
| 272 Register zr = AppropriateZeroRegFor(rd); | 272 Register zr = AppropriateZeroRegFor(rd); |
| 273 Sbc(rd, zr, operand); | 273 Sbc(rd, zr, operand); |
| 274 } | 274 } |
| 275 | 275 |
| 276 | 276 |
| 277 void MacroAssembler::Ngcs(const Register& rd, | 277 void MacroAssembler::Ngcs(const Register& rd, |
| 278 const Operand& operand) { | 278 const Operand& operand) { |
| 279 ASSERT(allow_macro_instructions_); | 279 DCHECK(allow_macro_instructions_); |
| 280 ASSERT(!rd.IsZero()); | 280 DCHECK(!rd.IsZero()); |
| 281 Register zr = AppropriateZeroRegFor(rd); | 281 Register zr = AppropriateZeroRegFor(rd); |
| 282 Sbcs(rd, zr, operand); | 282 Sbcs(rd, zr, operand); |
| 283 } | 283 } |
| 284 | 284 |
| 285 | 285 |
| 286 void MacroAssembler::Mvn(const Register& rd, uint64_t imm) { | 286 void MacroAssembler::Mvn(const Register& rd, uint64_t imm) { |
| 287 ASSERT(allow_macro_instructions_); | 287 DCHECK(allow_macro_instructions_); |
| 288 ASSERT(!rd.IsZero()); | 288 DCHECK(!rd.IsZero()); |
| 289 Mov(rd, ~imm); | 289 Mov(rd, ~imm); |
| 290 } | 290 } |
| 291 | 291 |
| 292 | 292 |
| 293 #define DEFINE_FUNCTION(FN, REGTYPE, REG, OP) \ | 293 #define DEFINE_FUNCTION(FN, REGTYPE, REG, OP) \ |
| 294 void MacroAssembler::FN(const REGTYPE REG, const MemOperand& addr) { \ | 294 void MacroAssembler::FN(const REGTYPE REG, const MemOperand& addr) { \ |
| 295 ASSERT(allow_macro_instructions_); \ | 295 DCHECK(allow_macro_instructions_); \ |
| 296 LoadStoreMacro(REG, addr, OP); \ | 296 LoadStoreMacro(REG, addr, OP); \ |
| 297 } | 297 } |
| 298 LS_MACRO_LIST(DEFINE_FUNCTION) | 298 LS_MACRO_LIST(DEFINE_FUNCTION) |
| 299 #undef DEFINE_FUNCTION | 299 #undef DEFINE_FUNCTION |
| 300 | 300 |
| 301 | 301 |
| 302 void MacroAssembler::Asr(const Register& rd, | 302 void MacroAssembler::Asr(const Register& rd, |
| 303 const Register& rn, | 303 const Register& rn, |
| 304 unsigned shift) { | 304 unsigned shift) { |
| 305 ASSERT(allow_macro_instructions_); | 305 DCHECK(allow_macro_instructions_); |
| 306 ASSERT(!rd.IsZero()); | 306 DCHECK(!rd.IsZero()); |
| 307 asr(rd, rn, shift); | 307 asr(rd, rn, shift); |
| 308 } | 308 } |
| 309 | 309 |
| 310 | 310 |
| 311 void MacroAssembler::Asr(const Register& rd, | 311 void MacroAssembler::Asr(const Register& rd, |
| 312 const Register& rn, | 312 const Register& rn, |
| 313 const Register& rm) { | 313 const Register& rm) { |
| 314 ASSERT(allow_macro_instructions_); | 314 DCHECK(allow_macro_instructions_); |
| 315 ASSERT(!rd.IsZero()); | 315 DCHECK(!rd.IsZero()); |
| 316 asrv(rd, rn, rm); | 316 asrv(rd, rn, rm); |
| 317 } | 317 } |
| 318 | 318 |
| 319 | 319 |
| 320 void MacroAssembler::B(Label* label) { | 320 void MacroAssembler::B(Label* label) { |
| 321 b(label); | 321 b(label); |
| 322 CheckVeneerPool(false, false); | 322 CheckVeneerPool(false, false); |
| 323 } | 323 } |
| 324 | 324 |
| 325 | 325 |
| 326 void MacroAssembler::B(Condition cond, Label* label) { | 326 void MacroAssembler::B(Condition cond, Label* label) { |
| 327 ASSERT(allow_macro_instructions_); | 327 DCHECK(allow_macro_instructions_); |
| 328 B(label, cond); | 328 B(label, cond); |
| 329 } | 329 } |
| 330 | 330 |
| 331 | 331 |
| 332 void MacroAssembler::Bfi(const Register& rd, | 332 void MacroAssembler::Bfi(const Register& rd, |
| 333 const Register& rn, | 333 const Register& rn, |
| 334 unsigned lsb, | 334 unsigned lsb, |
| 335 unsigned width) { | 335 unsigned width) { |
| 336 ASSERT(allow_macro_instructions_); | 336 DCHECK(allow_macro_instructions_); |
| 337 ASSERT(!rd.IsZero()); | 337 DCHECK(!rd.IsZero()); |
| 338 bfi(rd, rn, lsb, width); | 338 bfi(rd, rn, lsb, width); |
| 339 } | 339 } |
| 340 | 340 |
| 341 | 341 |
| 342 void MacroAssembler::Bfxil(const Register& rd, | 342 void MacroAssembler::Bfxil(const Register& rd, |
| 343 const Register& rn, | 343 const Register& rn, |
| 344 unsigned lsb, | 344 unsigned lsb, |
| 345 unsigned width) { | 345 unsigned width) { |
| 346 ASSERT(allow_macro_instructions_); | 346 DCHECK(allow_macro_instructions_); |
| 347 ASSERT(!rd.IsZero()); | 347 DCHECK(!rd.IsZero()); |
| 348 bfxil(rd, rn, lsb, width); | 348 bfxil(rd, rn, lsb, width); |
| 349 } | 349 } |
| 350 | 350 |
| 351 | 351 |
| 352 void MacroAssembler::Bind(Label* label) { | 352 void MacroAssembler::Bind(Label* label) { |
| 353 ASSERT(allow_macro_instructions_); | 353 DCHECK(allow_macro_instructions_); |
| 354 bind(label); | 354 bind(label); |
| 355 } | 355 } |
| 356 | 356 |
| 357 | 357 |
| 358 void MacroAssembler::Bl(Label* label) { | 358 void MacroAssembler::Bl(Label* label) { |
| 359 ASSERT(allow_macro_instructions_); | 359 DCHECK(allow_macro_instructions_); |
| 360 bl(label); | 360 bl(label); |
| 361 } | 361 } |
| 362 | 362 |
| 363 | 363 |
| 364 void MacroAssembler::Blr(const Register& xn) { | 364 void MacroAssembler::Blr(const Register& xn) { |
| 365 ASSERT(allow_macro_instructions_); | 365 DCHECK(allow_macro_instructions_); |
| 366 ASSERT(!xn.IsZero()); | 366 DCHECK(!xn.IsZero()); |
| 367 blr(xn); | 367 blr(xn); |
| 368 } | 368 } |
| 369 | 369 |
| 370 | 370 |
| 371 void MacroAssembler::Br(const Register& xn) { | 371 void MacroAssembler::Br(const Register& xn) { |
| 372 ASSERT(allow_macro_instructions_); | 372 DCHECK(allow_macro_instructions_); |
| 373 ASSERT(!xn.IsZero()); | 373 DCHECK(!xn.IsZero()); |
| 374 br(xn); | 374 br(xn); |
| 375 } | 375 } |
| 376 | 376 |
| 377 | 377 |
| 378 void MacroAssembler::Brk(int code) { | 378 void MacroAssembler::Brk(int code) { |
| 379 ASSERT(allow_macro_instructions_); | 379 DCHECK(allow_macro_instructions_); |
| 380 brk(code); | 380 brk(code); |
| 381 } | 381 } |
| 382 | 382 |
| 383 | 383 |
| 384 void MacroAssembler::Cinc(const Register& rd, | 384 void MacroAssembler::Cinc(const Register& rd, |
| 385 const Register& rn, | 385 const Register& rn, |
| 386 Condition cond) { | 386 Condition cond) { |
| 387 ASSERT(allow_macro_instructions_); | 387 DCHECK(allow_macro_instructions_); |
| 388 ASSERT(!rd.IsZero()); | 388 DCHECK(!rd.IsZero()); |
| 389 ASSERT((cond != al) && (cond != nv)); | 389 DCHECK((cond != al) && (cond != nv)); |
| 390 cinc(rd, rn, cond); | 390 cinc(rd, rn, cond); |
| 391 } | 391 } |
| 392 | 392 |
| 393 | 393 |
| 394 void MacroAssembler::Cinv(const Register& rd, | 394 void MacroAssembler::Cinv(const Register& rd, |
| 395 const Register& rn, | 395 const Register& rn, |
| 396 Condition cond) { | 396 Condition cond) { |
| 397 ASSERT(allow_macro_instructions_); | 397 DCHECK(allow_macro_instructions_); |
| 398 ASSERT(!rd.IsZero()); | 398 DCHECK(!rd.IsZero()); |
| 399 ASSERT((cond != al) && (cond != nv)); | 399 DCHECK((cond != al) && (cond != nv)); |
| 400 cinv(rd, rn, cond); | 400 cinv(rd, rn, cond); |
| 401 } | 401 } |
| 402 | 402 |
| 403 | 403 |
| 404 void MacroAssembler::Cls(const Register& rd, const Register& rn) { | 404 void MacroAssembler::Cls(const Register& rd, const Register& rn) { |
| 405 ASSERT(allow_macro_instructions_); | 405 DCHECK(allow_macro_instructions_); |
| 406 ASSERT(!rd.IsZero()); | 406 DCHECK(!rd.IsZero()); |
| 407 cls(rd, rn); | 407 cls(rd, rn); |
| 408 } | 408 } |
| 409 | 409 |
| 410 | 410 |
| 411 void MacroAssembler::Clz(const Register& rd, const Register& rn) { | 411 void MacroAssembler::Clz(const Register& rd, const Register& rn) { |
| 412 ASSERT(allow_macro_instructions_); | 412 DCHECK(allow_macro_instructions_); |
| 413 ASSERT(!rd.IsZero()); | 413 DCHECK(!rd.IsZero()); |
| 414 clz(rd, rn); | 414 clz(rd, rn); |
| 415 } | 415 } |
| 416 | 416 |
| 417 | 417 |
| 418 void MacroAssembler::Cneg(const Register& rd, | 418 void MacroAssembler::Cneg(const Register& rd, |
| 419 const Register& rn, | 419 const Register& rn, |
| 420 Condition cond) { | 420 Condition cond) { |
| 421 ASSERT(allow_macro_instructions_); | 421 DCHECK(allow_macro_instructions_); |
| 422 ASSERT(!rd.IsZero()); | 422 DCHECK(!rd.IsZero()); |
| 423 ASSERT((cond != al) && (cond != nv)); | 423 DCHECK((cond != al) && (cond != nv)); |
| 424 cneg(rd, rn, cond); | 424 cneg(rd, rn, cond); |
| 425 } | 425 } |
| 426 | 426 |
| 427 | 427 |
| 428 // Conditionally zero the destination register. Only X registers are supported | 428 // Conditionally zero the destination register. Only X registers are supported |
| 429 // due to the truncation side-effect when used on W registers. | 429 // due to the truncation side-effect when used on W registers. |
| 430 void MacroAssembler::CzeroX(const Register& rd, | 430 void MacroAssembler::CzeroX(const Register& rd, |
| 431 Condition cond) { | 431 Condition cond) { |
| 432 ASSERT(allow_macro_instructions_); | 432 DCHECK(allow_macro_instructions_); |
| 433 ASSERT(!rd.IsSP() && rd.Is64Bits()); | 433 DCHECK(!rd.IsSP() && rd.Is64Bits()); |
| 434 ASSERT((cond != al) && (cond != nv)); | 434 DCHECK((cond != al) && (cond != nv)); |
| 435 csel(rd, xzr, rd, cond); | 435 csel(rd, xzr, rd, cond); |
| 436 } | 436 } |
| 437 | 437 |
| 438 | 438 |
| 439 // Conditionally move a value into the destination register. Only X registers | 439 // Conditionally move a value into the destination register. Only X registers |
| 440 // are supported due to the truncation side-effect when used on W registers. | 440 // are supported due to the truncation side-effect when used on W registers. |
| 441 void MacroAssembler::CmovX(const Register& rd, | 441 void MacroAssembler::CmovX(const Register& rd, |
| 442 const Register& rn, | 442 const Register& rn, |
| 443 Condition cond) { | 443 Condition cond) { |
| 444 ASSERT(allow_macro_instructions_); | 444 DCHECK(allow_macro_instructions_); |
| 445 ASSERT(!rd.IsSP()); | 445 DCHECK(!rd.IsSP()); |
| 446 ASSERT(rd.Is64Bits() && rn.Is64Bits()); | 446 DCHECK(rd.Is64Bits() && rn.Is64Bits()); |
| 447 ASSERT((cond != al) && (cond != nv)); | 447 DCHECK((cond != al) && (cond != nv)); |
| 448 if (!rd.is(rn)) { | 448 if (!rd.is(rn)) { |
| 449 csel(rd, rn, rd, cond); | 449 csel(rd, rn, rd, cond); |
| 450 } | 450 } |
| 451 } | 451 } |
| 452 | 452 |
| 453 | 453 |
| 454 void MacroAssembler::Cset(const Register& rd, Condition cond) { | 454 void MacroAssembler::Cset(const Register& rd, Condition cond) { |
| 455 ASSERT(allow_macro_instructions_); | 455 DCHECK(allow_macro_instructions_); |
| 456 ASSERT(!rd.IsZero()); | 456 DCHECK(!rd.IsZero()); |
| 457 ASSERT((cond != al) && (cond != nv)); | 457 DCHECK((cond != al) && (cond != nv)); |
| 458 cset(rd, cond); | 458 cset(rd, cond); |
| 459 } | 459 } |
| 460 | 460 |
| 461 | 461 |
| 462 void MacroAssembler::Csetm(const Register& rd, Condition cond) { | 462 void MacroAssembler::Csetm(const Register& rd, Condition cond) { |
| 463 ASSERT(allow_macro_instructions_); | 463 DCHECK(allow_macro_instructions_); |
| 464 ASSERT(!rd.IsZero()); | 464 DCHECK(!rd.IsZero()); |
| 465 ASSERT((cond != al) && (cond != nv)); | 465 DCHECK((cond != al) && (cond != nv)); |
| 466 csetm(rd, cond); | 466 csetm(rd, cond); |
| 467 } | 467 } |
| 468 | 468 |
| 469 | 469 |
| 470 void MacroAssembler::Csinc(const Register& rd, | 470 void MacroAssembler::Csinc(const Register& rd, |
| 471 const Register& rn, | 471 const Register& rn, |
| 472 const Register& rm, | 472 const Register& rm, |
| 473 Condition cond) { | 473 Condition cond) { |
| 474 ASSERT(allow_macro_instructions_); | 474 DCHECK(allow_macro_instructions_); |
| 475 ASSERT(!rd.IsZero()); | 475 DCHECK(!rd.IsZero()); |
| 476 ASSERT((cond != al) && (cond != nv)); | 476 DCHECK((cond != al) && (cond != nv)); |
| 477 csinc(rd, rn, rm, cond); | 477 csinc(rd, rn, rm, cond); |
| 478 } | 478 } |
| 479 | 479 |
| 480 | 480 |
| 481 void MacroAssembler::Csinv(const Register& rd, | 481 void MacroAssembler::Csinv(const Register& rd, |
| 482 const Register& rn, | 482 const Register& rn, |
| 483 const Register& rm, | 483 const Register& rm, |
| 484 Condition cond) { | 484 Condition cond) { |
| 485 ASSERT(allow_macro_instructions_); | 485 DCHECK(allow_macro_instructions_); |
| 486 ASSERT(!rd.IsZero()); | 486 DCHECK(!rd.IsZero()); |
| 487 ASSERT((cond != al) && (cond != nv)); | 487 DCHECK((cond != al) && (cond != nv)); |
| 488 csinv(rd, rn, rm, cond); | 488 csinv(rd, rn, rm, cond); |
| 489 } | 489 } |
| 490 | 490 |
| 491 | 491 |
| 492 void MacroAssembler::Csneg(const Register& rd, | 492 void MacroAssembler::Csneg(const Register& rd, |
| 493 const Register& rn, | 493 const Register& rn, |
| 494 const Register& rm, | 494 const Register& rm, |
| 495 Condition cond) { | 495 Condition cond) { |
| 496 ASSERT(allow_macro_instructions_); | 496 DCHECK(allow_macro_instructions_); |
| 497 ASSERT(!rd.IsZero()); | 497 DCHECK(!rd.IsZero()); |
| 498 ASSERT((cond != al) && (cond != nv)); | 498 DCHECK((cond != al) && (cond != nv)); |
| 499 csneg(rd, rn, rm, cond); | 499 csneg(rd, rn, rm, cond); |
| 500 } | 500 } |
| 501 | 501 |
| 502 | 502 |
| 503 void MacroAssembler::Dmb(BarrierDomain domain, BarrierType type) { | 503 void MacroAssembler::Dmb(BarrierDomain domain, BarrierType type) { |
| 504 ASSERT(allow_macro_instructions_); | 504 DCHECK(allow_macro_instructions_); |
| 505 dmb(domain, type); | 505 dmb(domain, type); |
| 506 } | 506 } |
| 507 | 507 |
| 508 | 508 |
| 509 void MacroAssembler::Dsb(BarrierDomain domain, BarrierType type) { | 509 void MacroAssembler::Dsb(BarrierDomain domain, BarrierType type) { |
| 510 ASSERT(allow_macro_instructions_); | 510 DCHECK(allow_macro_instructions_); |
| 511 dsb(domain, type); | 511 dsb(domain, type); |
| 512 } | 512 } |
| 513 | 513 |
| 514 | 514 |
| 515 void MacroAssembler::Debug(const char* message, uint32_t code, Instr params) { | 515 void MacroAssembler::Debug(const char* message, uint32_t code, Instr params) { |
| 516 ASSERT(allow_macro_instructions_); | 516 DCHECK(allow_macro_instructions_); |
| 517 debug(message, code, params); | 517 debug(message, code, params); |
| 518 } | 518 } |
| 519 | 519 |
| 520 | 520 |
| 521 void MacroAssembler::Extr(const Register& rd, | 521 void MacroAssembler::Extr(const Register& rd, |
| 522 const Register& rn, | 522 const Register& rn, |
| 523 const Register& rm, | 523 const Register& rm, |
| 524 unsigned lsb) { | 524 unsigned lsb) { |
| 525 ASSERT(allow_macro_instructions_); | 525 DCHECK(allow_macro_instructions_); |
| 526 ASSERT(!rd.IsZero()); | 526 DCHECK(!rd.IsZero()); |
| 527 extr(rd, rn, rm, lsb); | 527 extr(rd, rn, rm, lsb); |
| 528 } | 528 } |
| 529 | 529 |
| 530 | 530 |
| 531 void MacroAssembler::Fabs(const FPRegister& fd, const FPRegister& fn) { | 531 void MacroAssembler::Fabs(const FPRegister& fd, const FPRegister& fn) { |
| 532 ASSERT(allow_macro_instructions_); | 532 DCHECK(allow_macro_instructions_); |
| 533 fabs(fd, fn); | 533 fabs(fd, fn); |
| 534 } | 534 } |
| 535 | 535 |
| 536 | 536 |
| 537 void MacroAssembler::Fadd(const FPRegister& fd, | 537 void MacroAssembler::Fadd(const FPRegister& fd, |
| 538 const FPRegister& fn, | 538 const FPRegister& fn, |
| 539 const FPRegister& fm) { | 539 const FPRegister& fm) { |
| 540 ASSERT(allow_macro_instructions_); | 540 DCHECK(allow_macro_instructions_); |
| 541 fadd(fd, fn, fm); | 541 fadd(fd, fn, fm); |
| 542 } | 542 } |
| 543 | 543 |
| 544 | 544 |
| 545 void MacroAssembler::Fccmp(const FPRegister& fn, | 545 void MacroAssembler::Fccmp(const FPRegister& fn, |
| 546 const FPRegister& fm, | 546 const FPRegister& fm, |
| 547 StatusFlags nzcv, | 547 StatusFlags nzcv, |
| 548 Condition cond) { | 548 Condition cond) { |
| 549 ASSERT(allow_macro_instructions_); | 549 DCHECK(allow_macro_instructions_); |
| 550 ASSERT((cond != al) && (cond != nv)); | 550 DCHECK((cond != al) && (cond != nv)); |
| 551 fccmp(fn, fm, nzcv, cond); | 551 fccmp(fn, fm, nzcv, cond); |
| 552 } | 552 } |
| 553 | 553 |
| 554 | 554 |
| 555 void MacroAssembler::Fcmp(const FPRegister& fn, const FPRegister& fm) { | 555 void MacroAssembler::Fcmp(const FPRegister& fn, const FPRegister& fm) { |
| 556 ASSERT(allow_macro_instructions_); | 556 DCHECK(allow_macro_instructions_); |
| 557 fcmp(fn, fm); | 557 fcmp(fn, fm); |
| 558 } | 558 } |
| 559 | 559 |
| 560 | 560 |
| 561 void MacroAssembler::Fcmp(const FPRegister& fn, double value) { | 561 void MacroAssembler::Fcmp(const FPRegister& fn, double value) { |
| 562 ASSERT(allow_macro_instructions_); | 562 DCHECK(allow_macro_instructions_); |
| 563 if (value != 0.0) { | 563 if (value != 0.0) { |
| 564 UseScratchRegisterScope temps(this); | 564 UseScratchRegisterScope temps(this); |
| 565 FPRegister tmp = temps.AcquireSameSizeAs(fn); | 565 FPRegister tmp = temps.AcquireSameSizeAs(fn); |
| 566 Fmov(tmp, value); | 566 Fmov(tmp, value); |
| 567 fcmp(fn, tmp); | 567 fcmp(fn, tmp); |
| 568 } else { | 568 } else { |
| 569 fcmp(fn, value); | 569 fcmp(fn, value); |
| 570 } | 570 } |
| 571 } | 571 } |
| 572 | 572 |
| 573 | 573 |
| 574 void MacroAssembler::Fcsel(const FPRegister& fd, | 574 void MacroAssembler::Fcsel(const FPRegister& fd, |
| 575 const FPRegister& fn, | 575 const FPRegister& fn, |
| 576 const FPRegister& fm, | 576 const FPRegister& fm, |
| 577 Condition cond) { | 577 Condition cond) { |
| 578 ASSERT(allow_macro_instructions_); | 578 DCHECK(allow_macro_instructions_); |
| 579 ASSERT((cond != al) && (cond != nv)); | 579 DCHECK((cond != al) && (cond != nv)); |
| 580 fcsel(fd, fn, fm, cond); | 580 fcsel(fd, fn, fm, cond); |
| 581 } | 581 } |
| 582 | 582 |
| 583 | 583 |
| 584 void MacroAssembler::Fcvt(const FPRegister& fd, const FPRegister& fn) { | 584 void MacroAssembler::Fcvt(const FPRegister& fd, const FPRegister& fn) { |
| 585 ASSERT(allow_macro_instructions_); | 585 DCHECK(allow_macro_instructions_); |
| 586 fcvt(fd, fn); | 586 fcvt(fd, fn); |
| 587 } | 587 } |
| 588 | 588 |
| 589 | 589 |
| 590 void MacroAssembler::Fcvtas(const Register& rd, const FPRegister& fn) { | 590 void MacroAssembler::Fcvtas(const Register& rd, const FPRegister& fn) { |
| 591 ASSERT(allow_macro_instructions_); | 591 DCHECK(allow_macro_instructions_); |
| 592 ASSERT(!rd.IsZero()); | 592 DCHECK(!rd.IsZero()); |
| 593 fcvtas(rd, fn); | 593 fcvtas(rd, fn); |
| 594 } | 594 } |
| 595 | 595 |
| 596 | 596 |
| 597 void MacroAssembler::Fcvtau(const Register& rd, const FPRegister& fn) { | 597 void MacroAssembler::Fcvtau(const Register& rd, const FPRegister& fn) { |
| 598 ASSERT(allow_macro_instructions_); | 598 DCHECK(allow_macro_instructions_); |
| 599 ASSERT(!rd.IsZero()); | 599 DCHECK(!rd.IsZero()); |
| 600 fcvtau(rd, fn); | 600 fcvtau(rd, fn); |
| 601 } | 601 } |
| 602 | 602 |
| 603 | 603 |
| 604 void MacroAssembler::Fcvtms(const Register& rd, const FPRegister& fn) { | 604 void MacroAssembler::Fcvtms(const Register& rd, const FPRegister& fn) { |
| 605 ASSERT(allow_macro_instructions_); | 605 DCHECK(allow_macro_instructions_); |
| 606 ASSERT(!rd.IsZero()); | 606 DCHECK(!rd.IsZero()); |
| 607 fcvtms(rd, fn); | 607 fcvtms(rd, fn); |
| 608 } | 608 } |
| 609 | 609 |
| 610 | 610 |
| 611 void MacroAssembler::Fcvtmu(const Register& rd, const FPRegister& fn) { | 611 void MacroAssembler::Fcvtmu(const Register& rd, const FPRegister& fn) { |
| 612 ASSERT(allow_macro_instructions_); | 612 DCHECK(allow_macro_instructions_); |
| 613 ASSERT(!rd.IsZero()); | 613 DCHECK(!rd.IsZero()); |
| 614 fcvtmu(rd, fn); | 614 fcvtmu(rd, fn); |
| 615 } | 615 } |
| 616 | 616 |
| 617 | 617 |
| 618 void MacroAssembler::Fcvtns(const Register& rd, const FPRegister& fn) { | 618 void MacroAssembler::Fcvtns(const Register& rd, const FPRegister& fn) { |
| 619 ASSERT(allow_macro_instructions_); | 619 DCHECK(allow_macro_instructions_); |
| 620 ASSERT(!rd.IsZero()); | 620 DCHECK(!rd.IsZero()); |
| 621 fcvtns(rd, fn); | 621 fcvtns(rd, fn); |
| 622 } | 622 } |
| 623 | 623 |
| 624 | 624 |
| 625 void MacroAssembler::Fcvtnu(const Register& rd, const FPRegister& fn) { | 625 void MacroAssembler::Fcvtnu(const Register& rd, const FPRegister& fn) { |
| 626 ASSERT(allow_macro_instructions_); | 626 DCHECK(allow_macro_instructions_); |
| 627 ASSERT(!rd.IsZero()); | 627 DCHECK(!rd.IsZero()); |
| 628 fcvtnu(rd, fn); | 628 fcvtnu(rd, fn); |
| 629 } | 629 } |
| 630 | 630 |
| 631 | 631 |
| 632 void MacroAssembler::Fcvtzs(const Register& rd, const FPRegister& fn) { | 632 void MacroAssembler::Fcvtzs(const Register& rd, const FPRegister& fn) { |
| 633 ASSERT(allow_macro_instructions_); | 633 DCHECK(allow_macro_instructions_); |
| 634 ASSERT(!rd.IsZero()); | 634 DCHECK(!rd.IsZero()); |
| 635 fcvtzs(rd, fn); | 635 fcvtzs(rd, fn); |
| 636 } | 636 } |
| 637 void MacroAssembler::Fcvtzu(const Register& rd, const FPRegister& fn) { | 637 void MacroAssembler::Fcvtzu(const Register& rd, const FPRegister& fn) { |
| 638 ASSERT(allow_macro_instructions_); | 638 DCHECK(allow_macro_instructions_); |
| 639 ASSERT(!rd.IsZero()); | 639 DCHECK(!rd.IsZero()); |
| 640 fcvtzu(rd, fn); | 640 fcvtzu(rd, fn); |
| 641 } | 641 } |
| 642 | 642 |
| 643 | 643 |
| 644 void MacroAssembler::Fdiv(const FPRegister& fd, | 644 void MacroAssembler::Fdiv(const FPRegister& fd, |
| 645 const FPRegister& fn, | 645 const FPRegister& fn, |
| 646 const FPRegister& fm) { | 646 const FPRegister& fm) { |
| 647 ASSERT(allow_macro_instructions_); | 647 DCHECK(allow_macro_instructions_); |
| 648 fdiv(fd, fn, fm); | 648 fdiv(fd, fn, fm); |
| 649 } | 649 } |
| 650 | 650 |
| 651 | 651 |
| 652 void MacroAssembler::Fmadd(const FPRegister& fd, | 652 void MacroAssembler::Fmadd(const FPRegister& fd, |
| 653 const FPRegister& fn, | 653 const FPRegister& fn, |
| 654 const FPRegister& fm, | 654 const FPRegister& fm, |
| 655 const FPRegister& fa) { | 655 const FPRegister& fa) { |
| 656 ASSERT(allow_macro_instructions_); | 656 DCHECK(allow_macro_instructions_); |
| 657 fmadd(fd, fn, fm, fa); | 657 fmadd(fd, fn, fm, fa); |
| 658 } | 658 } |
| 659 | 659 |
| 660 | 660 |
| 661 void MacroAssembler::Fmax(const FPRegister& fd, | 661 void MacroAssembler::Fmax(const FPRegister& fd, |
| 662 const FPRegister& fn, | 662 const FPRegister& fn, |
| 663 const FPRegister& fm) { | 663 const FPRegister& fm) { |
| 664 ASSERT(allow_macro_instructions_); | 664 DCHECK(allow_macro_instructions_); |
| 665 fmax(fd, fn, fm); | 665 fmax(fd, fn, fm); |
| 666 } | 666 } |
| 667 | 667 |
| 668 | 668 |
| 669 void MacroAssembler::Fmaxnm(const FPRegister& fd, | 669 void MacroAssembler::Fmaxnm(const FPRegister& fd, |
| 670 const FPRegister& fn, | 670 const FPRegister& fn, |
| 671 const FPRegister& fm) { | 671 const FPRegister& fm) { |
| 672 ASSERT(allow_macro_instructions_); | 672 DCHECK(allow_macro_instructions_); |
| 673 fmaxnm(fd, fn, fm); | 673 fmaxnm(fd, fn, fm); |
| 674 } | 674 } |
| 675 | 675 |
| 676 | 676 |
| 677 void MacroAssembler::Fmin(const FPRegister& fd, | 677 void MacroAssembler::Fmin(const FPRegister& fd, |
| 678 const FPRegister& fn, | 678 const FPRegister& fn, |
| 679 const FPRegister& fm) { | 679 const FPRegister& fm) { |
| 680 ASSERT(allow_macro_instructions_); | 680 DCHECK(allow_macro_instructions_); |
| 681 fmin(fd, fn, fm); | 681 fmin(fd, fn, fm); |
| 682 } | 682 } |
| 683 | 683 |
| 684 | 684 |
| 685 void MacroAssembler::Fminnm(const FPRegister& fd, | 685 void MacroAssembler::Fminnm(const FPRegister& fd, |
| 686 const FPRegister& fn, | 686 const FPRegister& fn, |
| 687 const FPRegister& fm) { | 687 const FPRegister& fm) { |
| 688 ASSERT(allow_macro_instructions_); | 688 DCHECK(allow_macro_instructions_); |
| 689 fminnm(fd, fn, fm); | 689 fminnm(fd, fn, fm); |
| 690 } | 690 } |
| 691 | 691 |
| 692 | 692 |
| 693 void MacroAssembler::Fmov(FPRegister fd, FPRegister fn) { | 693 void MacroAssembler::Fmov(FPRegister fd, FPRegister fn) { |
| 694 ASSERT(allow_macro_instructions_); | 694 DCHECK(allow_macro_instructions_); |
| 695 // Only emit an instruction if fd and fn are different, and they are both D | 695 // Only emit an instruction if fd and fn are different, and they are both D |
| 696 // registers. fmov(s0, s0) is not a no-op because it clears the top word of | 696 // registers. fmov(s0, s0) is not a no-op because it clears the top word of |
| 697 // d0. Technically, fmov(d0, d0) is not a no-op either because it clears the | 697 // d0. Technically, fmov(d0, d0) is not a no-op either because it clears the |
| 698 // top of q0, but FPRegister does not currently support Q registers. | 698 // top of q0, but FPRegister does not currently support Q registers. |
| 699 if (!fd.Is(fn) || !fd.Is64Bits()) { | 699 if (!fd.Is(fn) || !fd.Is64Bits()) { |
| 700 fmov(fd, fn); | 700 fmov(fd, fn); |
| 701 } | 701 } |
| 702 } | 702 } |
| 703 | 703 |
| 704 | 704 |
| 705 void MacroAssembler::Fmov(FPRegister fd, Register rn) { | 705 void MacroAssembler::Fmov(FPRegister fd, Register rn) { |
| 706 ASSERT(allow_macro_instructions_); | 706 DCHECK(allow_macro_instructions_); |
| 707 fmov(fd, rn); | 707 fmov(fd, rn); |
| 708 } | 708 } |
| 709 | 709 |
| 710 | 710 |
| 711 void MacroAssembler::Fmov(FPRegister fd, double imm) { | 711 void MacroAssembler::Fmov(FPRegister fd, double imm) { |
| 712 ASSERT(allow_macro_instructions_); | 712 DCHECK(allow_macro_instructions_); |
| 713 if (fd.Is32Bits()) { | 713 if (fd.Is32Bits()) { |
| 714 Fmov(fd, static_cast<float>(imm)); | 714 Fmov(fd, static_cast<float>(imm)); |
| 715 return; | 715 return; |
| 716 } | 716 } |
| 717 | 717 |
| 718 ASSERT(fd.Is64Bits()); | 718 DCHECK(fd.Is64Bits()); |
| 719 if (IsImmFP64(imm)) { | 719 if (IsImmFP64(imm)) { |
| 720 fmov(fd, imm); | 720 fmov(fd, imm); |
| 721 } else if ((imm == 0.0) && (copysign(1.0, imm) == 1.0)) { | 721 } else if ((imm == 0.0) && (copysign(1.0, imm) == 1.0)) { |
| 722 fmov(fd, xzr); | 722 fmov(fd, xzr); |
| 723 } else { | 723 } else { |
| 724 Ldr(fd, imm); | 724 Ldr(fd, imm); |
| 725 } | 725 } |
| 726 } | 726 } |
| 727 | 727 |
| 728 | 728 |
| 729 void MacroAssembler::Fmov(FPRegister fd, float imm) { | 729 void MacroAssembler::Fmov(FPRegister fd, float imm) { |
| 730 ASSERT(allow_macro_instructions_); | 730 DCHECK(allow_macro_instructions_); |
| 731 if (fd.Is64Bits()) { | 731 if (fd.Is64Bits()) { |
| 732 Fmov(fd, static_cast<double>(imm)); | 732 Fmov(fd, static_cast<double>(imm)); |
| 733 return; | 733 return; |
| 734 } | 734 } |
| 735 | 735 |
| 736 ASSERT(fd.Is32Bits()); | 736 DCHECK(fd.Is32Bits()); |
| 737 if (IsImmFP32(imm)) { | 737 if (IsImmFP32(imm)) { |
| 738 fmov(fd, imm); | 738 fmov(fd, imm); |
| 739 } else if ((imm == 0.0) && (copysign(1.0, imm) == 1.0)) { | 739 } else if ((imm == 0.0) && (copysign(1.0, imm) == 1.0)) { |
| 740 fmov(fd, wzr); | 740 fmov(fd, wzr); |
| 741 } else { | 741 } else { |
| 742 UseScratchRegisterScope temps(this); | 742 UseScratchRegisterScope temps(this); |
| 743 Register tmp = temps.AcquireW(); | 743 Register tmp = temps.AcquireW(); |
| 744 // TODO(all): Use Assembler::ldr(const FPRegister& ft, float imm). | 744 // TODO(all): Use Assembler::ldr(const FPRegister& ft, float imm). |
| 745 Mov(tmp, float_to_rawbits(imm)); | 745 Mov(tmp, float_to_rawbits(imm)); |
| 746 Fmov(fd, tmp); | 746 Fmov(fd, tmp); |
| 747 } | 747 } |
| 748 } | 748 } |
| 749 | 749 |
| 750 | 750 |
| 751 void MacroAssembler::Fmov(Register rd, FPRegister fn) { | 751 void MacroAssembler::Fmov(Register rd, FPRegister fn) { |
| 752 ASSERT(allow_macro_instructions_); | 752 DCHECK(allow_macro_instructions_); |
| 753 ASSERT(!rd.IsZero()); | 753 DCHECK(!rd.IsZero()); |
| 754 fmov(rd, fn); | 754 fmov(rd, fn); |
| 755 } | 755 } |
| 756 | 756 |
| 757 | 757 |
| 758 void MacroAssembler::Fmsub(const FPRegister& fd, | 758 void MacroAssembler::Fmsub(const FPRegister& fd, |
| 759 const FPRegister& fn, | 759 const FPRegister& fn, |
| 760 const FPRegister& fm, | 760 const FPRegister& fm, |
| 761 const FPRegister& fa) { | 761 const FPRegister& fa) { |
| 762 ASSERT(allow_macro_instructions_); | 762 DCHECK(allow_macro_instructions_); |
| 763 fmsub(fd, fn, fm, fa); | 763 fmsub(fd, fn, fm, fa); |
| 764 } | 764 } |
| 765 | 765 |
| 766 | 766 |
| 767 void MacroAssembler::Fmul(const FPRegister& fd, | 767 void MacroAssembler::Fmul(const FPRegister& fd, |
| 768 const FPRegister& fn, | 768 const FPRegister& fn, |
| 769 const FPRegister& fm) { | 769 const FPRegister& fm) { |
| 770 ASSERT(allow_macro_instructions_); | 770 DCHECK(allow_macro_instructions_); |
| 771 fmul(fd, fn, fm); | 771 fmul(fd, fn, fm); |
| 772 } | 772 } |
| 773 | 773 |
| 774 | 774 |
| 775 void MacroAssembler::Fneg(const FPRegister& fd, const FPRegister& fn) { | 775 void MacroAssembler::Fneg(const FPRegister& fd, const FPRegister& fn) { |
| 776 ASSERT(allow_macro_instructions_); | 776 DCHECK(allow_macro_instructions_); |
| 777 fneg(fd, fn); | 777 fneg(fd, fn); |
| 778 } | 778 } |
| 779 | 779 |
| 780 | 780 |
| 781 void MacroAssembler::Fnmadd(const FPRegister& fd, | 781 void MacroAssembler::Fnmadd(const FPRegister& fd, |
| 782 const FPRegister& fn, | 782 const FPRegister& fn, |
| 783 const FPRegister& fm, | 783 const FPRegister& fm, |
| 784 const FPRegister& fa) { | 784 const FPRegister& fa) { |
| 785 ASSERT(allow_macro_instructions_); | 785 DCHECK(allow_macro_instructions_); |
| 786 fnmadd(fd, fn, fm, fa); | 786 fnmadd(fd, fn, fm, fa); |
| 787 } | 787 } |
| 788 | 788 |
| 789 | 789 |
| 790 void MacroAssembler::Fnmsub(const FPRegister& fd, | 790 void MacroAssembler::Fnmsub(const FPRegister& fd, |
| 791 const FPRegister& fn, | 791 const FPRegister& fn, |
| 792 const FPRegister& fm, | 792 const FPRegister& fm, |
| 793 const FPRegister& fa) { | 793 const FPRegister& fa) { |
| 794 ASSERT(allow_macro_instructions_); | 794 DCHECK(allow_macro_instructions_); |
| 795 fnmsub(fd, fn, fm, fa); | 795 fnmsub(fd, fn, fm, fa); |
| 796 } | 796 } |
| 797 | 797 |
| 798 | 798 |
| 799 void MacroAssembler::Frinta(const FPRegister& fd, const FPRegister& fn) { | 799 void MacroAssembler::Frinta(const FPRegister& fd, const FPRegister& fn) { |
| 800 ASSERT(allow_macro_instructions_); | 800 DCHECK(allow_macro_instructions_); |
| 801 frinta(fd, fn); | 801 frinta(fd, fn); |
| 802 } | 802 } |
| 803 | 803 |
| 804 | 804 |
| 805 void MacroAssembler::Frintm(const FPRegister& fd, const FPRegister& fn) { | 805 void MacroAssembler::Frintm(const FPRegister& fd, const FPRegister& fn) { |
| 806 ASSERT(allow_macro_instructions_); | 806 DCHECK(allow_macro_instructions_); |
| 807 frintm(fd, fn); | 807 frintm(fd, fn); |
| 808 } | 808 } |
| 809 | 809 |
| 810 | 810 |
| 811 void MacroAssembler::Frintn(const FPRegister& fd, const FPRegister& fn) { | 811 void MacroAssembler::Frintn(const FPRegister& fd, const FPRegister& fn) { |
| 812 ASSERT(allow_macro_instructions_); | 812 DCHECK(allow_macro_instructions_); |
| 813 frintn(fd, fn); | 813 frintn(fd, fn); |
| 814 } | 814 } |
| 815 | 815 |
| 816 | 816 |
| 817 void MacroAssembler::Frintz(const FPRegister& fd, const FPRegister& fn) { | 817 void MacroAssembler::Frintz(const FPRegister& fd, const FPRegister& fn) { |
| 818 ASSERT(allow_macro_instructions_); | 818 DCHECK(allow_macro_instructions_); |
| 819 frintz(fd, fn); | 819 frintz(fd, fn); |
| 820 } | 820 } |
| 821 | 821 |
| 822 | 822 |
| 823 void MacroAssembler::Fsqrt(const FPRegister& fd, const FPRegister& fn) { | 823 void MacroAssembler::Fsqrt(const FPRegister& fd, const FPRegister& fn) { |
| 824 ASSERT(allow_macro_instructions_); | 824 DCHECK(allow_macro_instructions_); |
| 825 fsqrt(fd, fn); | 825 fsqrt(fd, fn); |
| 826 } | 826 } |
| 827 | 827 |
| 828 | 828 |
| 829 void MacroAssembler::Fsub(const FPRegister& fd, | 829 void MacroAssembler::Fsub(const FPRegister& fd, |
| 830 const FPRegister& fn, | 830 const FPRegister& fn, |
| 831 const FPRegister& fm) { | 831 const FPRegister& fm) { |
| 832 ASSERT(allow_macro_instructions_); | 832 DCHECK(allow_macro_instructions_); |
| 833 fsub(fd, fn, fm); | 833 fsub(fd, fn, fm); |
| 834 } | 834 } |
| 835 | 835 |
| 836 | 836 |
| 837 void MacroAssembler::Hint(SystemHint code) { | 837 void MacroAssembler::Hint(SystemHint code) { |
| 838 ASSERT(allow_macro_instructions_); | 838 DCHECK(allow_macro_instructions_); |
| 839 hint(code); | 839 hint(code); |
| 840 } | 840 } |
| 841 | 841 |
| 842 | 842 |
| 843 void MacroAssembler::Hlt(int code) { | 843 void MacroAssembler::Hlt(int code) { |
| 844 ASSERT(allow_macro_instructions_); | 844 DCHECK(allow_macro_instructions_); |
| 845 hlt(code); | 845 hlt(code); |
| 846 } | 846 } |
| 847 | 847 |
| 848 | 848 |
| 849 void MacroAssembler::Isb() { | 849 void MacroAssembler::Isb() { |
| 850 ASSERT(allow_macro_instructions_); | 850 DCHECK(allow_macro_instructions_); |
| 851 isb(); | 851 isb(); |
| 852 } | 852 } |
| 853 | 853 |
| 854 | 854 |
| 855 void MacroAssembler::Ldnp(const CPURegister& rt, | 855 void MacroAssembler::Ldnp(const CPURegister& rt, |
| 856 const CPURegister& rt2, | 856 const CPURegister& rt2, |
| 857 const MemOperand& src) { | 857 const MemOperand& src) { |
| 858 ASSERT(allow_macro_instructions_); | 858 DCHECK(allow_macro_instructions_); |
| 859 ASSERT(!AreAliased(rt, rt2)); | 859 DCHECK(!AreAliased(rt, rt2)); |
| 860 ldnp(rt, rt2, src); | 860 ldnp(rt, rt2, src); |
| 861 } | 861 } |
| 862 | 862 |
| 863 | 863 |
| 864 void MacroAssembler::Ldp(const CPURegister& rt, | 864 void MacroAssembler::Ldp(const CPURegister& rt, |
| 865 const CPURegister& rt2, | 865 const CPURegister& rt2, |
| 866 const MemOperand& src) { | 866 const MemOperand& src) { |
| 867 ASSERT(allow_macro_instructions_); | 867 DCHECK(allow_macro_instructions_); |
| 868 ASSERT(!AreAliased(rt, rt2)); | 868 DCHECK(!AreAliased(rt, rt2)); |
| 869 ldp(rt, rt2, src); | 869 ldp(rt, rt2, src); |
| 870 } | 870 } |
| 871 | 871 |
| 872 | 872 |
| 873 void MacroAssembler::Ldpsw(const Register& rt, | 873 void MacroAssembler::Ldpsw(const Register& rt, |
| 874 const Register& rt2, | 874 const Register& rt2, |
| 875 const MemOperand& src) { | 875 const MemOperand& src) { |
| 876 ASSERT(allow_macro_instructions_); | 876 DCHECK(allow_macro_instructions_); |
| 877 ASSERT(!rt.IsZero()); | 877 DCHECK(!rt.IsZero()); |
| 878 ASSERT(!rt2.IsZero()); | 878 DCHECK(!rt2.IsZero()); |
| 879 ldpsw(rt, rt2, src); | 879 ldpsw(rt, rt2, src); |
| 880 } | 880 } |
| 881 | 881 |
| 882 | 882 |
| 883 void MacroAssembler::Ldr(const CPURegister& rt, const Immediate& imm) { | 883 void MacroAssembler::Ldr(const CPURegister& rt, const Immediate& imm) { |
| 884 ASSERT(allow_macro_instructions_); | 884 DCHECK(allow_macro_instructions_); |
| 885 ldr(rt, imm); | 885 ldr(rt, imm); |
| 886 } | 886 } |
| 887 | 887 |
| 888 | 888 |
| 889 void MacroAssembler::Ldr(const CPURegister& rt, double imm) { | 889 void MacroAssembler::Ldr(const CPURegister& rt, double imm) { |
| 890 ASSERT(allow_macro_instructions_); | 890 DCHECK(allow_macro_instructions_); |
| 891 ASSERT(rt.Is64Bits()); | 891 DCHECK(rt.Is64Bits()); |
| 892 ldr(rt, Immediate(double_to_rawbits(imm))); | 892 ldr(rt, Immediate(double_to_rawbits(imm))); |
| 893 } | 893 } |
| 894 | 894 |
| 895 | 895 |
| 896 void MacroAssembler::Lsl(const Register& rd, | 896 void MacroAssembler::Lsl(const Register& rd, |
| 897 const Register& rn, | 897 const Register& rn, |
| 898 unsigned shift) { | 898 unsigned shift) { |
| 899 ASSERT(allow_macro_instructions_); | 899 DCHECK(allow_macro_instructions_); |
| 900 ASSERT(!rd.IsZero()); | 900 DCHECK(!rd.IsZero()); |
| 901 lsl(rd, rn, shift); | 901 lsl(rd, rn, shift); |
| 902 } | 902 } |
| 903 | 903 |
| 904 | 904 |
| 905 void MacroAssembler::Lsl(const Register& rd, | 905 void MacroAssembler::Lsl(const Register& rd, |
| 906 const Register& rn, | 906 const Register& rn, |
| 907 const Register& rm) { | 907 const Register& rm) { |
| 908 ASSERT(allow_macro_instructions_); | 908 DCHECK(allow_macro_instructions_); |
| 909 ASSERT(!rd.IsZero()); | 909 DCHECK(!rd.IsZero()); |
| 910 lslv(rd, rn, rm); | 910 lslv(rd, rn, rm); |
| 911 } | 911 } |
| 912 | 912 |
| 913 | 913 |
| 914 void MacroAssembler::Lsr(const Register& rd, | 914 void MacroAssembler::Lsr(const Register& rd, |
| 915 const Register& rn, | 915 const Register& rn, |
| 916 unsigned shift) { | 916 unsigned shift) { |
| 917 ASSERT(allow_macro_instructions_); | 917 DCHECK(allow_macro_instructions_); |
| 918 ASSERT(!rd.IsZero()); | 918 DCHECK(!rd.IsZero()); |
| 919 lsr(rd, rn, shift); | 919 lsr(rd, rn, shift); |
| 920 } | 920 } |
| 921 | 921 |
| 922 | 922 |
| 923 void MacroAssembler::Lsr(const Register& rd, | 923 void MacroAssembler::Lsr(const Register& rd, |
| 924 const Register& rn, | 924 const Register& rn, |
| 925 const Register& rm) { | 925 const Register& rm) { |
| 926 ASSERT(allow_macro_instructions_); | 926 DCHECK(allow_macro_instructions_); |
| 927 ASSERT(!rd.IsZero()); | 927 DCHECK(!rd.IsZero()); |
| 928 lsrv(rd, rn, rm); | 928 lsrv(rd, rn, rm); |
| 929 } | 929 } |
| 930 | 930 |
| 931 | 931 |
| 932 void MacroAssembler::Madd(const Register& rd, | 932 void MacroAssembler::Madd(const Register& rd, |
| 933 const Register& rn, | 933 const Register& rn, |
| 934 const Register& rm, | 934 const Register& rm, |
| 935 const Register& ra) { | 935 const Register& ra) { |
| 936 ASSERT(allow_macro_instructions_); | 936 DCHECK(allow_macro_instructions_); |
| 937 ASSERT(!rd.IsZero()); | 937 DCHECK(!rd.IsZero()); |
| 938 madd(rd, rn, rm, ra); | 938 madd(rd, rn, rm, ra); |
| 939 } | 939 } |
| 940 | 940 |
| 941 | 941 |
| 942 void MacroAssembler::Mneg(const Register& rd, | 942 void MacroAssembler::Mneg(const Register& rd, |
| 943 const Register& rn, | 943 const Register& rn, |
| 944 const Register& rm) { | 944 const Register& rm) { |
| 945 ASSERT(allow_macro_instructions_); | 945 DCHECK(allow_macro_instructions_); |
| 946 ASSERT(!rd.IsZero()); | 946 DCHECK(!rd.IsZero()); |
| 947 mneg(rd, rn, rm); | 947 mneg(rd, rn, rm); |
| 948 } | 948 } |
| 949 | 949 |
| 950 | 950 |
| 951 void MacroAssembler::Mov(const Register& rd, const Register& rn) { | 951 void MacroAssembler::Mov(const Register& rd, const Register& rn) { |
| 952 ASSERT(allow_macro_instructions_); | 952 DCHECK(allow_macro_instructions_); |
| 953 ASSERT(!rd.IsZero()); | 953 DCHECK(!rd.IsZero()); |
| 954 // Emit a register move only if the registers are distinct, or if they are | 954 // Emit a register move only if the registers are distinct, or if they are |
| 955 // not X registers. Note that mov(w0, w0) is not a no-op because it clears | 955 // not X registers. Note that mov(w0, w0) is not a no-op because it clears |
| 956 // the top word of x0. | 956 // the top word of x0. |
| 957 if (!rd.Is(rn) || !rd.Is64Bits()) { | 957 if (!rd.Is(rn) || !rd.Is64Bits()) { |
| 958 Assembler::mov(rd, rn); | 958 Assembler::mov(rd, rn); |
| 959 } | 959 } |
| 960 } | 960 } |
| 961 | 961 |
| 962 | 962 |
| 963 void MacroAssembler::Movk(const Register& rd, uint64_t imm, int shift) { | 963 void MacroAssembler::Movk(const Register& rd, uint64_t imm, int shift) { |
| 964 ASSERT(allow_macro_instructions_); | 964 DCHECK(allow_macro_instructions_); |
| 965 ASSERT(!rd.IsZero()); | 965 DCHECK(!rd.IsZero()); |
| 966 movk(rd, imm, shift); | 966 movk(rd, imm, shift); |
| 967 } | 967 } |
| 968 | 968 |
| 969 | 969 |
| 970 void MacroAssembler::Mrs(const Register& rt, SystemRegister sysreg) { | 970 void MacroAssembler::Mrs(const Register& rt, SystemRegister sysreg) { |
| 971 ASSERT(allow_macro_instructions_); | 971 DCHECK(allow_macro_instructions_); |
| 972 ASSERT(!rt.IsZero()); | 972 DCHECK(!rt.IsZero()); |
| 973 mrs(rt, sysreg); | 973 mrs(rt, sysreg); |
| 974 } | 974 } |
| 975 | 975 |
| 976 | 976 |
| 977 void MacroAssembler::Msr(SystemRegister sysreg, const Register& rt) { | 977 void MacroAssembler::Msr(SystemRegister sysreg, const Register& rt) { |
| 978 ASSERT(allow_macro_instructions_); | 978 DCHECK(allow_macro_instructions_); |
| 979 msr(sysreg, rt); | 979 msr(sysreg, rt); |
| 980 } | 980 } |
| 981 | 981 |
| 982 | 982 |
| 983 void MacroAssembler::Msub(const Register& rd, | 983 void MacroAssembler::Msub(const Register& rd, |
| 984 const Register& rn, | 984 const Register& rn, |
| 985 const Register& rm, | 985 const Register& rm, |
| 986 const Register& ra) { | 986 const Register& ra) { |
| 987 ASSERT(allow_macro_instructions_); | 987 DCHECK(allow_macro_instructions_); |
| 988 ASSERT(!rd.IsZero()); | 988 DCHECK(!rd.IsZero()); |
| 989 msub(rd, rn, rm, ra); | 989 msub(rd, rn, rm, ra); |
| 990 } | 990 } |
| 991 | 991 |
| 992 | 992 |
| 993 void MacroAssembler::Mul(const Register& rd, | 993 void MacroAssembler::Mul(const Register& rd, |
| 994 const Register& rn, | 994 const Register& rn, |
| 995 const Register& rm) { | 995 const Register& rm) { |
| 996 ASSERT(allow_macro_instructions_); | 996 DCHECK(allow_macro_instructions_); |
| 997 ASSERT(!rd.IsZero()); | 997 DCHECK(!rd.IsZero()); |
| 998 mul(rd, rn, rm); | 998 mul(rd, rn, rm); |
| 999 } | 999 } |
| 1000 | 1000 |
| 1001 | 1001 |
| 1002 void MacroAssembler::Rbit(const Register& rd, const Register& rn) { | 1002 void MacroAssembler::Rbit(const Register& rd, const Register& rn) { |
| 1003 ASSERT(allow_macro_instructions_); | 1003 DCHECK(allow_macro_instructions_); |
| 1004 ASSERT(!rd.IsZero()); | 1004 DCHECK(!rd.IsZero()); |
| 1005 rbit(rd, rn); | 1005 rbit(rd, rn); |
| 1006 } | 1006 } |
| 1007 | 1007 |
| 1008 | 1008 |
| 1009 void MacroAssembler::Ret(const Register& xn) { | 1009 void MacroAssembler::Ret(const Register& xn) { |
| 1010 ASSERT(allow_macro_instructions_); | 1010 DCHECK(allow_macro_instructions_); |
| 1011 ASSERT(!xn.IsZero()); | 1011 DCHECK(!xn.IsZero()); |
| 1012 ret(xn); | 1012 ret(xn); |
| 1013 CheckVeneerPool(false, false); | 1013 CheckVeneerPool(false, false); |
| 1014 } | 1014 } |
| 1015 | 1015 |
| 1016 | 1016 |
| 1017 void MacroAssembler::Rev(const Register& rd, const Register& rn) { | 1017 void MacroAssembler::Rev(const Register& rd, const Register& rn) { |
| 1018 ASSERT(allow_macro_instructions_); | 1018 DCHECK(allow_macro_instructions_); |
| 1019 ASSERT(!rd.IsZero()); | 1019 DCHECK(!rd.IsZero()); |
| 1020 rev(rd, rn); | 1020 rev(rd, rn); |
| 1021 } | 1021 } |
| 1022 | 1022 |
| 1023 | 1023 |
| 1024 void MacroAssembler::Rev16(const Register& rd, const Register& rn) { | 1024 void MacroAssembler::Rev16(const Register& rd, const Register& rn) { |
| 1025 ASSERT(allow_macro_instructions_); | 1025 DCHECK(allow_macro_instructions_); |
| 1026 ASSERT(!rd.IsZero()); | 1026 DCHECK(!rd.IsZero()); |
| 1027 rev16(rd, rn); | 1027 rev16(rd, rn); |
| 1028 } | 1028 } |
| 1029 | 1029 |
| 1030 | 1030 |
| 1031 void MacroAssembler::Rev32(const Register& rd, const Register& rn) { | 1031 void MacroAssembler::Rev32(const Register& rd, const Register& rn) { |
| 1032 ASSERT(allow_macro_instructions_); | 1032 DCHECK(allow_macro_instructions_); |
| 1033 ASSERT(!rd.IsZero()); | 1033 DCHECK(!rd.IsZero()); |
| 1034 rev32(rd, rn); | 1034 rev32(rd, rn); |
| 1035 } | 1035 } |
| 1036 | 1036 |
| 1037 | 1037 |
| 1038 void MacroAssembler::Ror(const Register& rd, | 1038 void MacroAssembler::Ror(const Register& rd, |
| 1039 const Register& rs, | 1039 const Register& rs, |
| 1040 unsigned shift) { | 1040 unsigned shift) { |
| 1041 ASSERT(allow_macro_instructions_); | 1041 DCHECK(allow_macro_instructions_); |
| 1042 ASSERT(!rd.IsZero()); | 1042 DCHECK(!rd.IsZero()); |
| 1043 ror(rd, rs, shift); | 1043 ror(rd, rs, shift); |
| 1044 } | 1044 } |
| 1045 | 1045 |
| 1046 | 1046 |
| 1047 void MacroAssembler::Ror(const Register& rd, | 1047 void MacroAssembler::Ror(const Register& rd, |
| 1048 const Register& rn, | 1048 const Register& rn, |
| 1049 const Register& rm) { | 1049 const Register& rm) { |
| 1050 ASSERT(allow_macro_instructions_); | 1050 DCHECK(allow_macro_instructions_); |
| 1051 ASSERT(!rd.IsZero()); | 1051 DCHECK(!rd.IsZero()); |
| 1052 rorv(rd, rn, rm); | 1052 rorv(rd, rn, rm); |
| 1053 } | 1053 } |
| 1054 | 1054 |
| 1055 | 1055 |
| 1056 void MacroAssembler::Sbfiz(const Register& rd, | 1056 void MacroAssembler::Sbfiz(const Register& rd, |
| 1057 const Register& rn, | 1057 const Register& rn, |
| 1058 unsigned lsb, | 1058 unsigned lsb, |
| 1059 unsigned width) { | 1059 unsigned width) { |
| 1060 ASSERT(allow_macro_instructions_); | 1060 DCHECK(allow_macro_instructions_); |
| 1061 ASSERT(!rd.IsZero()); | 1061 DCHECK(!rd.IsZero()); |
| 1062 sbfiz(rd, rn, lsb, width); | 1062 sbfiz(rd, rn, lsb, width); |
| 1063 } | 1063 } |
| 1064 | 1064 |
| 1065 | 1065 |
| 1066 void MacroAssembler::Sbfx(const Register& rd, | 1066 void MacroAssembler::Sbfx(const Register& rd, |
| 1067 const Register& rn, | 1067 const Register& rn, |
| 1068 unsigned lsb, | 1068 unsigned lsb, |
| 1069 unsigned width) { | 1069 unsigned width) { |
| 1070 ASSERT(allow_macro_instructions_); | 1070 DCHECK(allow_macro_instructions_); |
| 1071 ASSERT(!rd.IsZero()); | 1071 DCHECK(!rd.IsZero()); |
| 1072 sbfx(rd, rn, lsb, width); | 1072 sbfx(rd, rn, lsb, width); |
| 1073 } | 1073 } |
| 1074 | 1074 |
| 1075 | 1075 |
| 1076 void MacroAssembler::Scvtf(const FPRegister& fd, | 1076 void MacroAssembler::Scvtf(const FPRegister& fd, |
| 1077 const Register& rn, | 1077 const Register& rn, |
| 1078 unsigned fbits) { | 1078 unsigned fbits) { |
| 1079 ASSERT(allow_macro_instructions_); | 1079 DCHECK(allow_macro_instructions_); |
| 1080 scvtf(fd, rn, fbits); | 1080 scvtf(fd, rn, fbits); |
| 1081 } | 1081 } |
| 1082 | 1082 |
| 1083 | 1083 |
| 1084 void MacroAssembler::Sdiv(const Register& rd, | 1084 void MacroAssembler::Sdiv(const Register& rd, |
| 1085 const Register& rn, | 1085 const Register& rn, |
| 1086 const Register& rm) { | 1086 const Register& rm) { |
| 1087 ASSERT(allow_macro_instructions_); | 1087 DCHECK(allow_macro_instructions_); |
| 1088 ASSERT(!rd.IsZero()); | 1088 DCHECK(!rd.IsZero()); |
| 1089 sdiv(rd, rn, rm); | 1089 sdiv(rd, rn, rm); |
| 1090 } | 1090 } |
| 1091 | 1091 |
| 1092 | 1092 |
| 1093 void MacroAssembler::Smaddl(const Register& rd, | 1093 void MacroAssembler::Smaddl(const Register& rd, |
| 1094 const Register& rn, | 1094 const Register& rn, |
| 1095 const Register& rm, | 1095 const Register& rm, |
| 1096 const Register& ra) { | 1096 const Register& ra) { |
| 1097 ASSERT(allow_macro_instructions_); | 1097 DCHECK(allow_macro_instructions_); |
| 1098 ASSERT(!rd.IsZero()); | 1098 DCHECK(!rd.IsZero()); |
| 1099 smaddl(rd, rn, rm, ra); | 1099 smaddl(rd, rn, rm, ra); |
| 1100 } | 1100 } |
| 1101 | 1101 |
| 1102 | 1102 |
| 1103 void MacroAssembler::Smsubl(const Register& rd, | 1103 void MacroAssembler::Smsubl(const Register& rd, |
| 1104 const Register& rn, | 1104 const Register& rn, |
| 1105 const Register& rm, | 1105 const Register& rm, |
| 1106 const Register& ra) { | 1106 const Register& ra) { |
| 1107 ASSERT(allow_macro_instructions_); | 1107 DCHECK(allow_macro_instructions_); |
| 1108 ASSERT(!rd.IsZero()); | 1108 DCHECK(!rd.IsZero()); |
| 1109 smsubl(rd, rn, rm, ra); | 1109 smsubl(rd, rn, rm, ra); |
| 1110 } | 1110 } |
| 1111 | 1111 |
| 1112 | 1112 |
| 1113 void MacroAssembler::Smull(const Register& rd, | 1113 void MacroAssembler::Smull(const Register& rd, |
| 1114 const Register& rn, | 1114 const Register& rn, |
| 1115 const Register& rm) { | 1115 const Register& rm) { |
| 1116 ASSERT(allow_macro_instructions_); | 1116 DCHECK(allow_macro_instructions_); |
| 1117 ASSERT(!rd.IsZero()); | 1117 DCHECK(!rd.IsZero()); |
| 1118 smull(rd, rn, rm); | 1118 smull(rd, rn, rm); |
| 1119 } | 1119 } |
| 1120 | 1120 |
| 1121 | 1121 |
| 1122 void MacroAssembler::Smulh(const Register& rd, | 1122 void MacroAssembler::Smulh(const Register& rd, |
| 1123 const Register& rn, | 1123 const Register& rn, |
| 1124 const Register& rm) { | 1124 const Register& rm) { |
| 1125 ASSERT(allow_macro_instructions_); | 1125 DCHECK(allow_macro_instructions_); |
| 1126 ASSERT(!rd.IsZero()); | 1126 DCHECK(!rd.IsZero()); |
| 1127 smulh(rd, rn, rm); | 1127 smulh(rd, rn, rm); |
| 1128 } | 1128 } |
| 1129 | 1129 |
| 1130 | 1130 |
| 1131 void MacroAssembler::Stnp(const CPURegister& rt, | 1131 void MacroAssembler::Stnp(const CPURegister& rt, |
| 1132 const CPURegister& rt2, | 1132 const CPURegister& rt2, |
| 1133 const MemOperand& dst) { | 1133 const MemOperand& dst) { |
| 1134 ASSERT(allow_macro_instructions_); | 1134 DCHECK(allow_macro_instructions_); |
| 1135 stnp(rt, rt2, dst); | 1135 stnp(rt, rt2, dst); |
| 1136 } | 1136 } |
| 1137 | 1137 |
| 1138 | 1138 |
| 1139 void MacroAssembler::Stp(const CPURegister& rt, | 1139 void MacroAssembler::Stp(const CPURegister& rt, |
| 1140 const CPURegister& rt2, | 1140 const CPURegister& rt2, |
| 1141 const MemOperand& dst) { | 1141 const MemOperand& dst) { |
| 1142 ASSERT(allow_macro_instructions_); | 1142 DCHECK(allow_macro_instructions_); |
| 1143 stp(rt, rt2, dst); | 1143 stp(rt, rt2, dst); |
| 1144 } | 1144 } |
| 1145 | 1145 |
| 1146 | 1146 |
| 1147 void MacroAssembler::Sxtb(const Register& rd, const Register& rn) { | 1147 void MacroAssembler::Sxtb(const Register& rd, const Register& rn) { |
| 1148 ASSERT(allow_macro_instructions_); | 1148 DCHECK(allow_macro_instructions_); |
| 1149 ASSERT(!rd.IsZero()); | 1149 DCHECK(!rd.IsZero()); |
| 1150 sxtb(rd, rn); | 1150 sxtb(rd, rn); |
| 1151 } | 1151 } |
| 1152 | 1152 |
| 1153 | 1153 |
| 1154 void MacroAssembler::Sxth(const Register& rd, const Register& rn) { | 1154 void MacroAssembler::Sxth(const Register& rd, const Register& rn) { |
| 1155 ASSERT(allow_macro_instructions_); | 1155 DCHECK(allow_macro_instructions_); |
| 1156 ASSERT(!rd.IsZero()); | 1156 DCHECK(!rd.IsZero()); |
| 1157 sxth(rd, rn); | 1157 sxth(rd, rn); |
| 1158 } | 1158 } |
| 1159 | 1159 |
| 1160 | 1160 |
| 1161 void MacroAssembler::Sxtw(const Register& rd, const Register& rn) { | 1161 void MacroAssembler::Sxtw(const Register& rd, const Register& rn) { |
| 1162 ASSERT(allow_macro_instructions_); | 1162 DCHECK(allow_macro_instructions_); |
| 1163 ASSERT(!rd.IsZero()); | 1163 DCHECK(!rd.IsZero()); |
| 1164 sxtw(rd, rn); | 1164 sxtw(rd, rn); |
| 1165 } | 1165 } |
| 1166 | 1166 |
| 1167 | 1167 |
| 1168 void MacroAssembler::Ubfiz(const Register& rd, | 1168 void MacroAssembler::Ubfiz(const Register& rd, |
| 1169 const Register& rn, | 1169 const Register& rn, |
| 1170 unsigned lsb, | 1170 unsigned lsb, |
| 1171 unsigned width) { | 1171 unsigned width) { |
| 1172 ASSERT(allow_macro_instructions_); | 1172 DCHECK(allow_macro_instructions_); |
| 1173 ASSERT(!rd.IsZero()); | 1173 DCHECK(!rd.IsZero()); |
| 1174 ubfiz(rd, rn, lsb, width); | 1174 ubfiz(rd, rn, lsb, width); |
| 1175 } | 1175 } |
| 1176 | 1176 |
| 1177 | 1177 |
| 1178 void MacroAssembler::Ubfx(const Register& rd, | 1178 void MacroAssembler::Ubfx(const Register& rd, |
| 1179 const Register& rn, | 1179 const Register& rn, |
| 1180 unsigned lsb, | 1180 unsigned lsb, |
| 1181 unsigned width) { | 1181 unsigned width) { |
| 1182 ASSERT(allow_macro_instructions_); | 1182 DCHECK(allow_macro_instructions_); |
| 1183 ASSERT(!rd.IsZero()); | 1183 DCHECK(!rd.IsZero()); |
| 1184 ubfx(rd, rn, lsb, width); | 1184 ubfx(rd, rn, lsb, width); |
| 1185 } | 1185 } |
| 1186 | 1186 |
| 1187 | 1187 |
| 1188 void MacroAssembler::Ucvtf(const FPRegister& fd, | 1188 void MacroAssembler::Ucvtf(const FPRegister& fd, |
| 1189 const Register& rn, | 1189 const Register& rn, |
| 1190 unsigned fbits) { | 1190 unsigned fbits) { |
| 1191 ASSERT(allow_macro_instructions_); | 1191 DCHECK(allow_macro_instructions_); |
| 1192 ucvtf(fd, rn, fbits); | 1192 ucvtf(fd, rn, fbits); |
| 1193 } | 1193 } |
| 1194 | 1194 |
| 1195 | 1195 |
| 1196 void MacroAssembler::Udiv(const Register& rd, | 1196 void MacroAssembler::Udiv(const Register& rd, |
| 1197 const Register& rn, | 1197 const Register& rn, |
| 1198 const Register& rm) { | 1198 const Register& rm) { |
| 1199 ASSERT(allow_macro_instructions_); | 1199 DCHECK(allow_macro_instructions_); |
| 1200 ASSERT(!rd.IsZero()); | 1200 DCHECK(!rd.IsZero()); |
| 1201 udiv(rd, rn, rm); | 1201 udiv(rd, rn, rm); |
| 1202 } | 1202 } |
| 1203 | 1203 |
| 1204 | 1204 |
| 1205 void MacroAssembler::Umaddl(const Register& rd, | 1205 void MacroAssembler::Umaddl(const Register& rd, |
| 1206 const Register& rn, | 1206 const Register& rn, |
| 1207 const Register& rm, | 1207 const Register& rm, |
| 1208 const Register& ra) { | 1208 const Register& ra) { |
| 1209 ASSERT(allow_macro_instructions_); | 1209 DCHECK(allow_macro_instructions_); |
| 1210 ASSERT(!rd.IsZero()); | 1210 DCHECK(!rd.IsZero()); |
| 1211 umaddl(rd, rn, rm, ra); | 1211 umaddl(rd, rn, rm, ra); |
| 1212 } | 1212 } |
| 1213 | 1213 |
| 1214 | 1214 |
| 1215 void MacroAssembler::Umsubl(const Register& rd, | 1215 void MacroAssembler::Umsubl(const Register& rd, |
| 1216 const Register& rn, | 1216 const Register& rn, |
| 1217 const Register& rm, | 1217 const Register& rm, |
| 1218 const Register& ra) { | 1218 const Register& ra) { |
| 1219 ASSERT(allow_macro_instructions_); | 1219 DCHECK(allow_macro_instructions_); |
| 1220 ASSERT(!rd.IsZero()); | 1220 DCHECK(!rd.IsZero()); |
| 1221 umsubl(rd, rn, rm, ra); | 1221 umsubl(rd, rn, rm, ra); |
| 1222 } | 1222 } |
| 1223 | 1223 |
| 1224 | 1224 |
| 1225 void MacroAssembler::Uxtb(const Register& rd, const Register& rn) { | 1225 void MacroAssembler::Uxtb(const Register& rd, const Register& rn) { |
| 1226 ASSERT(allow_macro_instructions_); | 1226 DCHECK(allow_macro_instructions_); |
| 1227 ASSERT(!rd.IsZero()); | 1227 DCHECK(!rd.IsZero()); |
| 1228 uxtb(rd, rn); | 1228 uxtb(rd, rn); |
| 1229 } | 1229 } |
| 1230 | 1230 |
| 1231 | 1231 |
| 1232 void MacroAssembler::Uxth(const Register& rd, const Register& rn) { | 1232 void MacroAssembler::Uxth(const Register& rd, const Register& rn) { |
| 1233 ASSERT(allow_macro_instructions_); | 1233 DCHECK(allow_macro_instructions_); |
| 1234 ASSERT(!rd.IsZero()); | 1234 DCHECK(!rd.IsZero()); |
| 1235 uxth(rd, rn); | 1235 uxth(rd, rn); |
| 1236 } | 1236 } |
| 1237 | 1237 |
| 1238 | 1238 |
| 1239 void MacroAssembler::Uxtw(const Register& rd, const Register& rn) { | 1239 void MacroAssembler::Uxtw(const Register& rd, const Register& rn) { |
| 1240 ASSERT(allow_macro_instructions_); | 1240 DCHECK(allow_macro_instructions_); |
| 1241 ASSERT(!rd.IsZero()); | 1241 DCHECK(!rd.IsZero()); |
| 1242 uxtw(rd, rn); | 1242 uxtw(rd, rn); |
| 1243 } | 1243 } |
| 1244 | 1244 |
| 1245 | 1245 |
| 1246 void MacroAssembler::BumpSystemStackPointer(const Operand& space) { | 1246 void MacroAssembler::BumpSystemStackPointer(const Operand& space) { |
| 1247 ASSERT(!csp.Is(sp_)); | 1247 DCHECK(!csp.Is(sp_)); |
| 1248 if (!TmpList()->IsEmpty()) { | 1248 if (!TmpList()->IsEmpty()) { |
| 1249 if (CpuFeatures::IsSupported(ALWAYS_ALIGN_CSP)) { | 1249 if (CpuFeatures::IsSupported(ALWAYS_ALIGN_CSP)) { |
| 1250 UseScratchRegisterScope temps(this); | 1250 UseScratchRegisterScope temps(this); |
| 1251 Register temp = temps.AcquireX(); | 1251 Register temp = temps.AcquireX(); |
| 1252 Sub(temp, StackPointer(), space); | 1252 Sub(temp, StackPointer(), space); |
| 1253 Bic(csp, temp, 0xf); | 1253 Bic(csp, temp, 0xf); |
| 1254 } else { | 1254 } else { |
| 1255 Sub(csp, StackPointer(), space); | 1255 Sub(csp, StackPointer(), space); |
| 1256 } | 1256 } |
| 1257 } else { | 1257 } else { |
| 1258 // TODO(jbramley): Several callers rely on this not using scratch | 1258 // TODO(jbramley): Several callers rely on this not using scratch |
| 1259 // registers, so we use the assembler directly here. However, this means | 1259 // registers, so we use the assembler directly here. However, this means |
| 1260 // that large immediate values of 'space' cannot be handled cleanly. (Only | 1260 // that large immediate values of 'space' cannot be handled cleanly. (Only |
| 1261 // 24-bits immediates or values of 'space' that can be encoded in one | 1261 // 24-bits immediates or values of 'space' that can be encoded in one |
| 1262 // instruction are accepted.) Once we implement our flexible scratch | 1262 // instruction are accepted.) Once we implement our flexible scratch |
| 1263 // register idea, we could greatly simplify this function. | 1263 // register idea, we could greatly simplify this function. |
| 1264 InstructionAccurateScope scope(this); | 1264 InstructionAccurateScope scope(this); |
| 1265 ASSERT(space.IsImmediate()); | 1265 DCHECK(space.IsImmediate()); |
| 1266 // Align to 16 bytes. | 1266 // Align to 16 bytes. |
| 1267 uint64_t imm = RoundUp(space.ImmediateValue(), 0x10); | 1267 uint64_t imm = RoundUp(space.ImmediateValue(), 0x10); |
| 1268 ASSERT(is_uint24(imm)); | 1268 DCHECK(is_uint24(imm)); |
| 1269 | 1269 |
| 1270 Register source = StackPointer(); | 1270 Register source = StackPointer(); |
| 1271 if (CpuFeatures::IsSupported(ALWAYS_ALIGN_CSP)) { | 1271 if (CpuFeatures::IsSupported(ALWAYS_ALIGN_CSP)) { |
| 1272 bic(csp, source, 0xf); | 1272 bic(csp, source, 0xf); |
| 1273 source = csp; | 1273 source = csp; |
| 1274 } | 1274 } |
| 1275 if (!is_uint12(imm)) { | 1275 if (!is_uint12(imm)) { |
| 1276 int64_t imm_top_12_bits = imm >> 12; | 1276 int64_t imm_top_12_bits = imm >> 12; |
| 1277 sub(csp, source, imm_top_12_bits << 12); | 1277 sub(csp, source, imm_top_12_bits << 12); |
| 1278 source = csp; | 1278 source = csp; |
| 1279 imm -= imm_top_12_bits << 12; | 1279 imm -= imm_top_12_bits << 12; |
| 1280 } | 1280 } |
| 1281 if (imm > 0) { | 1281 if (imm > 0) { |
| 1282 sub(csp, source, imm); | 1282 sub(csp, source, imm); |
| 1283 } | 1283 } |
| 1284 } | 1284 } |
| 1285 AssertStackConsistency(); | 1285 AssertStackConsistency(); |
| 1286 } | 1286 } |
| 1287 | 1287 |
| 1288 | 1288 |
| 1289 void MacroAssembler::SyncSystemStackPointer() { | 1289 void MacroAssembler::SyncSystemStackPointer() { |
| 1290 ASSERT(emit_debug_code()); | 1290 DCHECK(emit_debug_code()); |
| 1291 ASSERT(!csp.Is(sp_)); | 1291 DCHECK(!csp.Is(sp_)); |
| 1292 { InstructionAccurateScope scope(this); | 1292 { InstructionAccurateScope scope(this); |
| 1293 if (CpuFeatures::IsSupported(ALWAYS_ALIGN_CSP)) { | 1293 if (CpuFeatures::IsSupported(ALWAYS_ALIGN_CSP)) { |
| 1294 bic(csp, StackPointer(), 0xf); | 1294 bic(csp, StackPointer(), 0xf); |
| 1295 } else { | 1295 } else { |
| 1296 mov(csp, StackPointer()); | 1296 mov(csp, StackPointer()); |
| 1297 } | 1297 } |
| 1298 } | 1298 } |
| 1299 AssertStackConsistency(); | 1299 AssertStackConsistency(); |
| 1300 } | 1300 } |
| 1301 | 1301 |
| 1302 | 1302 |
| 1303 void MacroAssembler::InitializeRootRegister() { | 1303 void MacroAssembler::InitializeRootRegister() { |
| 1304 ExternalReference roots_array_start = | 1304 ExternalReference roots_array_start = |
| 1305 ExternalReference::roots_array_start(isolate()); | 1305 ExternalReference::roots_array_start(isolate()); |
| 1306 Mov(root, Operand(roots_array_start)); | 1306 Mov(root, Operand(roots_array_start)); |
| 1307 } | 1307 } |
| 1308 | 1308 |
| 1309 | 1309 |
| 1310 void MacroAssembler::SmiTag(Register dst, Register src) { | 1310 void MacroAssembler::SmiTag(Register dst, Register src) { |
| 1311 STATIC_ASSERT(kXRegSizeInBits == | 1311 STATIC_ASSERT(kXRegSizeInBits == |
| 1312 static_cast<unsigned>(kSmiShift + kSmiValueSize)); | 1312 static_cast<unsigned>(kSmiShift + kSmiValueSize)); |
| 1313 ASSERT(dst.Is64Bits() && src.Is64Bits()); | 1313 DCHECK(dst.Is64Bits() && src.Is64Bits()); |
| 1314 Lsl(dst, src, kSmiShift); | 1314 Lsl(dst, src, kSmiShift); |
| 1315 } | 1315 } |
| 1316 | 1316 |
| 1317 | 1317 |
| 1318 void MacroAssembler::SmiTag(Register smi) { SmiTag(smi, smi); } | 1318 void MacroAssembler::SmiTag(Register smi) { SmiTag(smi, smi); } |
| 1319 | 1319 |
| 1320 | 1320 |
| 1321 void MacroAssembler::SmiUntag(Register dst, Register src) { | 1321 void MacroAssembler::SmiUntag(Register dst, Register src) { |
| 1322 STATIC_ASSERT(kXRegSizeInBits == | 1322 STATIC_ASSERT(kXRegSizeInBits == |
| 1323 static_cast<unsigned>(kSmiShift + kSmiValueSize)); | 1323 static_cast<unsigned>(kSmiShift + kSmiValueSize)); |
| 1324 ASSERT(dst.Is64Bits() && src.Is64Bits()); | 1324 DCHECK(dst.Is64Bits() && src.Is64Bits()); |
| 1325 if (FLAG_enable_slow_asserts) { | 1325 if (FLAG_enable_slow_asserts) { |
| 1326 AssertSmi(src); | 1326 AssertSmi(src); |
| 1327 } | 1327 } |
| 1328 Asr(dst, src, kSmiShift); | 1328 Asr(dst, src, kSmiShift); |
| 1329 } | 1329 } |
| 1330 | 1330 |
| 1331 | 1331 |
| 1332 void MacroAssembler::SmiUntag(Register smi) { SmiUntag(smi, smi); } | 1332 void MacroAssembler::SmiUntag(Register smi) { SmiUntag(smi, smi); } |
| 1333 | 1333 |
| 1334 | 1334 |
| 1335 void MacroAssembler::SmiUntagToDouble(FPRegister dst, | 1335 void MacroAssembler::SmiUntagToDouble(FPRegister dst, |
| 1336 Register src, | 1336 Register src, |
| 1337 UntagMode mode) { | 1337 UntagMode mode) { |
| 1338 ASSERT(dst.Is64Bits() && src.Is64Bits()); | 1338 DCHECK(dst.Is64Bits() && src.Is64Bits()); |
| 1339 if (FLAG_enable_slow_asserts && (mode == kNotSpeculativeUntag)) { | 1339 if (FLAG_enable_slow_asserts && (mode == kNotSpeculativeUntag)) { |
| 1340 AssertSmi(src); | 1340 AssertSmi(src); |
| 1341 } | 1341 } |
| 1342 Scvtf(dst, src, kSmiShift); | 1342 Scvtf(dst, src, kSmiShift); |
| 1343 } | 1343 } |
| 1344 | 1344 |
| 1345 | 1345 |
| 1346 void MacroAssembler::SmiUntagToFloat(FPRegister dst, | 1346 void MacroAssembler::SmiUntagToFloat(FPRegister dst, |
| 1347 Register src, | 1347 Register src, |
| 1348 UntagMode mode) { | 1348 UntagMode mode) { |
| 1349 ASSERT(dst.Is32Bits() && src.Is64Bits()); | 1349 DCHECK(dst.Is32Bits() && src.Is64Bits()); |
| 1350 if (FLAG_enable_slow_asserts && (mode == kNotSpeculativeUntag)) { | 1350 if (FLAG_enable_slow_asserts && (mode == kNotSpeculativeUntag)) { |
| 1351 AssertSmi(src); | 1351 AssertSmi(src); |
| 1352 } | 1352 } |
| 1353 Scvtf(dst, src, kSmiShift); | 1353 Scvtf(dst, src, kSmiShift); |
| 1354 } | 1354 } |
| 1355 | 1355 |
| 1356 | 1356 |
| 1357 void MacroAssembler::SmiTagAndPush(Register src) { | 1357 void MacroAssembler::SmiTagAndPush(Register src) { |
| 1358 STATIC_ASSERT((static_cast<unsigned>(kSmiShift) == kWRegSizeInBits) && | 1358 STATIC_ASSERT((static_cast<unsigned>(kSmiShift) == kWRegSizeInBits) && |
| 1359 (static_cast<unsigned>(kSmiValueSize) == kWRegSizeInBits) && | 1359 (static_cast<unsigned>(kSmiValueSize) == kWRegSizeInBits) && |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1374 Label* smi_label, | 1374 Label* smi_label, |
| 1375 Label* not_smi_label) { | 1375 Label* not_smi_label) { |
| 1376 STATIC_ASSERT((kSmiTagSize == 1) && (kSmiTag == 0)); | 1376 STATIC_ASSERT((kSmiTagSize == 1) && (kSmiTag == 0)); |
| 1377 // Check if the tag bit is set. | 1377 // Check if the tag bit is set. |
| 1378 if (smi_label) { | 1378 if (smi_label) { |
| 1379 Tbz(value, 0, smi_label); | 1379 Tbz(value, 0, smi_label); |
| 1380 if (not_smi_label) { | 1380 if (not_smi_label) { |
| 1381 B(not_smi_label); | 1381 B(not_smi_label); |
| 1382 } | 1382 } |
| 1383 } else { | 1383 } else { |
| 1384 ASSERT(not_smi_label); | 1384 DCHECK(not_smi_label); |
| 1385 Tbnz(value, 0, not_smi_label); | 1385 Tbnz(value, 0, not_smi_label); |
| 1386 } | 1386 } |
| 1387 } | 1387 } |
| 1388 | 1388 |
| 1389 | 1389 |
| 1390 void MacroAssembler::JumpIfNotSmi(Register value, Label* not_smi_label) { | 1390 void MacroAssembler::JumpIfNotSmi(Register value, Label* not_smi_label) { |
| 1391 JumpIfSmi(value, NULL, not_smi_label); | 1391 JumpIfSmi(value, NULL, not_smi_label); |
| 1392 } | 1392 } |
| 1393 | 1393 |
| 1394 | 1394 |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1491 | 1491 |
| 1492 | 1492 |
| 1493 void MacroAssembler::IsObjectJSStringType(Register object, | 1493 void MacroAssembler::IsObjectJSStringType(Register object, |
| 1494 Register type, | 1494 Register type, |
| 1495 Label* not_string, | 1495 Label* not_string, |
| 1496 Label* string) { | 1496 Label* string) { |
| 1497 Ldr(type, FieldMemOperand(object, HeapObject::kMapOffset)); | 1497 Ldr(type, FieldMemOperand(object, HeapObject::kMapOffset)); |
| 1498 Ldrb(type.W(), FieldMemOperand(type, Map::kInstanceTypeOffset)); | 1498 Ldrb(type.W(), FieldMemOperand(type, Map::kInstanceTypeOffset)); |
| 1499 | 1499 |
| 1500 STATIC_ASSERT(kStringTag == 0); | 1500 STATIC_ASSERT(kStringTag == 0); |
| 1501 ASSERT((string != NULL) || (not_string != NULL)); | 1501 DCHECK((string != NULL) || (not_string != NULL)); |
| 1502 if (string == NULL) { | 1502 if (string == NULL) { |
| 1503 TestAndBranchIfAnySet(type.W(), kIsNotStringMask, not_string); | 1503 TestAndBranchIfAnySet(type.W(), kIsNotStringMask, not_string); |
| 1504 } else if (not_string == NULL) { | 1504 } else if (not_string == NULL) { |
| 1505 TestAndBranchIfAllClear(type.W(), kIsNotStringMask, string); | 1505 TestAndBranchIfAllClear(type.W(), kIsNotStringMask, string); |
| 1506 } else { | 1506 } else { |
| 1507 TestAndBranchIfAnySet(type.W(), kIsNotStringMask, not_string); | 1507 TestAndBranchIfAnySet(type.W(), kIsNotStringMask, not_string); |
| 1508 B(string); | 1508 B(string); |
| 1509 } | 1509 } |
| 1510 } | 1510 } |
| 1511 | 1511 |
| 1512 | 1512 |
| 1513 void MacroAssembler::Push(Handle<Object> handle) { | 1513 void MacroAssembler::Push(Handle<Object> handle) { |
| 1514 UseScratchRegisterScope temps(this); | 1514 UseScratchRegisterScope temps(this); |
| 1515 Register tmp = temps.AcquireX(); | 1515 Register tmp = temps.AcquireX(); |
| 1516 Mov(tmp, Operand(handle)); | 1516 Mov(tmp, Operand(handle)); |
| 1517 Push(tmp); | 1517 Push(tmp); |
| 1518 } | 1518 } |
| 1519 | 1519 |
| 1520 | 1520 |
| 1521 void MacroAssembler::Claim(uint64_t count, uint64_t unit_size) { | 1521 void MacroAssembler::Claim(uint64_t count, uint64_t unit_size) { |
| 1522 uint64_t size = count * unit_size; | 1522 uint64_t size = count * unit_size; |
| 1523 | 1523 |
| 1524 if (size == 0) { | 1524 if (size == 0) { |
| 1525 return; | 1525 return; |
| 1526 } | 1526 } |
| 1527 | 1527 |
| 1528 if (csp.Is(StackPointer())) { | 1528 if (csp.Is(StackPointer())) { |
| 1529 ASSERT(size % 16 == 0); | 1529 DCHECK(size % 16 == 0); |
| 1530 } else { | 1530 } else { |
| 1531 BumpSystemStackPointer(size); | 1531 BumpSystemStackPointer(size); |
| 1532 } | 1532 } |
| 1533 | 1533 |
| 1534 Sub(StackPointer(), StackPointer(), size); | 1534 Sub(StackPointer(), StackPointer(), size); |
| 1535 } | 1535 } |
| 1536 | 1536 |
| 1537 | 1537 |
| 1538 void MacroAssembler::Claim(const Register& count, uint64_t unit_size) { | 1538 void MacroAssembler::Claim(const Register& count, uint64_t unit_size) { |
| 1539 if (unit_size == 0) return; | 1539 if (unit_size == 0) return; |
| 1540 ASSERT(IsPowerOf2(unit_size)); | 1540 DCHECK(IsPowerOf2(unit_size)); |
| 1541 | 1541 |
| 1542 const int shift = CountTrailingZeros(unit_size, kXRegSizeInBits); | 1542 const int shift = CountTrailingZeros(unit_size, kXRegSizeInBits); |
| 1543 const Operand size(count, LSL, shift); | 1543 const Operand size(count, LSL, shift); |
| 1544 | 1544 |
| 1545 if (size.IsZero()) { | 1545 if (size.IsZero()) { |
| 1546 return; | 1546 return; |
| 1547 } | 1547 } |
| 1548 | 1548 |
| 1549 if (!csp.Is(StackPointer())) { | 1549 if (!csp.Is(StackPointer())) { |
| 1550 BumpSystemStackPointer(size); | 1550 BumpSystemStackPointer(size); |
| 1551 } | 1551 } |
| 1552 | 1552 |
| 1553 Sub(StackPointer(), StackPointer(), size); | 1553 Sub(StackPointer(), StackPointer(), size); |
| 1554 } | 1554 } |
| 1555 | 1555 |
| 1556 | 1556 |
| 1557 void MacroAssembler::ClaimBySMI(const Register& count_smi, uint64_t unit_size) { | 1557 void MacroAssembler::ClaimBySMI(const Register& count_smi, uint64_t unit_size) { |
| 1558 ASSERT(unit_size == 0 || IsPowerOf2(unit_size)); | 1558 DCHECK(unit_size == 0 || IsPowerOf2(unit_size)); |
| 1559 const int shift = CountTrailingZeros(unit_size, kXRegSizeInBits) - kSmiShift; | 1559 const int shift = CountTrailingZeros(unit_size, kXRegSizeInBits) - kSmiShift; |
| 1560 const Operand size(count_smi, | 1560 const Operand size(count_smi, |
| 1561 (shift >= 0) ? (LSL) : (LSR), | 1561 (shift >= 0) ? (LSL) : (LSR), |
| 1562 (shift >= 0) ? (shift) : (-shift)); | 1562 (shift >= 0) ? (shift) : (-shift)); |
| 1563 | 1563 |
| 1564 if (size.IsZero()) { | 1564 if (size.IsZero()) { |
| 1565 return; | 1565 return; |
| 1566 } | 1566 } |
| 1567 | 1567 |
| 1568 if (!csp.Is(StackPointer())) { | 1568 if (!csp.Is(StackPointer())) { |
| 1569 BumpSystemStackPointer(size); | 1569 BumpSystemStackPointer(size); |
| 1570 } | 1570 } |
| 1571 | 1571 |
| 1572 Sub(StackPointer(), StackPointer(), size); | 1572 Sub(StackPointer(), StackPointer(), size); |
| 1573 } | 1573 } |
| 1574 | 1574 |
| 1575 | 1575 |
| 1576 void MacroAssembler::Drop(uint64_t count, uint64_t unit_size) { | 1576 void MacroAssembler::Drop(uint64_t count, uint64_t unit_size) { |
| 1577 uint64_t size = count * unit_size; | 1577 uint64_t size = count * unit_size; |
| 1578 | 1578 |
| 1579 if (size == 0) { | 1579 if (size == 0) { |
| 1580 return; | 1580 return; |
| 1581 } | 1581 } |
| 1582 | 1582 |
| 1583 Add(StackPointer(), StackPointer(), size); | 1583 Add(StackPointer(), StackPointer(), size); |
| 1584 | 1584 |
| 1585 if (csp.Is(StackPointer())) { | 1585 if (csp.Is(StackPointer())) { |
| 1586 ASSERT(size % 16 == 0); | 1586 DCHECK(size % 16 == 0); |
| 1587 } else if (emit_debug_code()) { | 1587 } else if (emit_debug_code()) { |
| 1588 // It is safe to leave csp where it is when unwinding the JavaScript stack, | 1588 // It is safe to leave csp where it is when unwinding the JavaScript stack, |
| 1589 // but if we keep it matching StackPointer, the simulator can detect memory | 1589 // but if we keep it matching StackPointer, the simulator can detect memory |
| 1590 // accesses in the now-free part of the stack. | 1590 // accesses in the now-free part of the stack. |
| 1591 SyncSystemStackPointer(); | 1591 SyncSystemStackPointer(); |
| 1592 } | 1592 } |
| 1593 } | 1593 } |
| 1594 | 1594 |
| 1595 | 1595 |
| 1596 void MacroAssembler::Drop(const Register& count, uint64_t unit_size) { | 1596 void MacroAssembler::Drop(const Register& count, uint64_t unit_size) { |
| 1597 if (unit_size == 0) return; | 1597 if (unit_size == 0) return; |
| 1598 ASSERT(IsPowerOf2(unit_size)); | 1598 DCHECK(IsPowerOf2(unit_size)); |
| 1599 | 1599 |
| 1600 const int shift = CountTrailingZeros(unit_size, kXRegSizeInBits); | 1600 const int shift = CountTrailingZeros(unit_size, kXRegSizeInBits); |
| 1601 const Operand size(count, LSL, shift); | 1601 const Operand size(count, LSL, shift); |
| 1602 | 1602 |
| 1603 if (size.IsZero()) { | 1603 if (size.IsZero()) { |
| 1604 return; | 1604 return; |
| 1605 } | 1605 } |
| 1606 | 1606 |
| 1607 Add(StackPointer(), StackPointer(), size); | 1607 Add(StackPointer(), StackPointer(), size); |
| 1608 | 1608 |
| 1609 if (!csp.Is(StackPointer()) && emit_debug_code()) { | 1609 if (!csp.Is(StackPointer()) && emit_debug_code()) { |
| 1610 // It is safe to leave csp where it is when unwinding the JavaScript stack, | 1610 // It is safe to leave csp where it is when unwinding the JavaScript stack, |
| 1611 // but if we keep it matching StackPointer, the simulator can detect memory | 1611 // but if we keep it matching StackPointer, the simulator can detect memory |
| 1612 // accesses in the now-free part of the stack. | 1612 // accesses in the now-free part of the stack. |
| 1613 SyncSystemStackPointer(); | 1613 SyncSystemStackPointer(); |
| 1614 } | 1614 } |
| 1615 } | 1615 } |
| 1616 | 1616 |
| 1617 | 1617 |
| 1618 void MacroAssembler::DropBySMI(const Register& count_smi, uint64_t unit_size) { | 1618 void MacroAssembler::DropBySMI(const Register& count_smi, uint64_t unit_size) { |
| 1619 ASSERT(unit_size == 0 || IsPowerOf2(unit_size)); | 1619 DCHECK(unit_size == 0 || IsPowerOf2(unit_size)); |
| 1620 const int shift = CountTrailingZeros(unit_size, kXRegSizeInBits) - kSmiShift; | 1620 const int shift = CountTrailingZeros(unit_size, kXRegSizeInBits) - kSmiShift; |
| 1621 const Operand size(count_smi, | 1621 const Operand size(count_smi, |
| 1622 (shift >= 0) ? (LSL) : (LSR), | 1622 (shift >= 0) ? (LSL) : (LSR), |
| 1623 (shift >= 0) ? (shift) : (-shift)); | 1623 (shift >= 0) ? (shift) : (-shift)); |
| 1624 | 1624 |
| 1625 if (size.IsZero()) { | 1625 if (size.IsZero()) { |
| 1626 return; | 1626 return; |
| 1627 } | 1627 } |
| 1628 | 1628 |
| 1629 Add(StackPointer(), StackPointer(), size); | 1629 Add(StackPointer(), StackPointer(), size); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1652 Cmp(lhs, rhs); | 1652 Cmp(lhs, rhs); |
| 1653 B(cond, label); | 1653 B(cond, label); |
| 1654 } | 1654 } |
| 1655 } | 1655 } |
| 1656 | 1656 |
| 1657 | 1657 |
| 1658 void MacroAssembler::TestAndBranchIfAnySet(const Register& reg, | 1658 void MacroAssembler::TestAndBranchIfAnySet(const Register& reg, |
| 1659 const uint64_t bit_pattern, | 1659 const uint64_t bit_pattern, |
| 1660 Label* label) { | 1660 Label* label) { |
| 1661 int bits = reg.SizeInBits(); | 1661 int bits = reg.SizeInBits(); |
| 1662 ASSERT(CountSetBits(bit_pattern, bits) > 0); | 1662 DCHECK(CountSetBits(bit_pattern, bits) > 0); |
| 1663 if (CountSetBits(bit_pattern, bits) == 1) { | 1663 if (CountSetBits(bit_pattern, bits) == 1) { |
| 1664 Tbnz(reg, MaskToBit(bit_pattern), label); | 1664 Tbnz(reg, MaskToBit(bit_pattern), label); |
| 1665 } else { | 1665 } else { |
| 1666 Tst(reg, bit_pattern); | 1666 Tst(reg, bit_pattern); |
| 1667 B(ne, label); | 1667 B(ne, label); |
| 1668 } | 1668 } |
| 1669 } | 1669 } |
| 1670 | 1670 |
| 1671 | 1671 |
| 1672 void MacroAssembler::TestAndBranchIfAllClear(const Register& reg, | 1672 void MacroAssembler::TestAndBranchIfAllClear(const Register& reg, |
| 1673 const uint64_t bit_pattern, | 1673 const uint64_t bit_pattern, |
| 1674 Label* label) { | 1674 Label* label) { |
| 1675 int bits = reg.SizeInBits(); | 1675 int bits = reg.SizeInBits(); |
| 1676 ASSERT(CountSetBits(bit_pattern, bits) > 0); | 1676 DCHECK(CountSetBits(bit_pattern, bits) > 0); |
| 1677 if (CountSetBits(bit_pattern, bits) == 1) { | 1677 if (CountSetBits(bit_pattern, bits) == 1) { |
| 1678 Tbz(reg, MaskToBit(bit_pattern), label); | 1678 Tbz(reg, MaskToBit(bit_pattern), label); |
| 1679 } else { | 1679 } else { |
| 1680 Tst(reg, bit_pattern); | 1680 Tst(reg, bit_pattern); |
| 1681 B(eq, label); | 1681 B(eq, label); |
| 1682 } | 1682 } |
| 1683 } | 1683 } |
| 1684 | 1684 |
| 1685 | 1685 |
| 1686 void MacroAssembler::InlineData(uint64_t data) { | 1686 void MacroAssembler::InlineData(uint64_t data) { |
| 1687 ASSERT(is_uint16(data)); | 1687 DCHECK(is_uint16(data)); |
| 1688 InstructionAccurateScope scope(this, 1); | 1688 InstructionAccurateScope scope(this, 1); |
| 1689 movz(xzr, data); | 1689 movz(xzr, data); |
| 1690 } | 1690 } |
| 1691 | 1691 |
| 1692 | 1692 |
| 1693 void MacroAssembler::EnableInstrumentation() { | 1693 void MacroAssembler::EnableInstrumentation() { |
| 1694 InstructionAccurateScope scope(this, 1); | 1694 InstructionAccurateScope scope(this, 1); |
| 1695 movn(xzr, InstrumentStateEnable); | 1695 movn(xzr, InstrumentStateEnable); |
| 1696 } | 1696 } |
| 1697 | 1697 |
| 1698 | 1698 |
| 1699 void MacroAssembler::DisableInstrumentation() { | 1699 void MacroAssembler::DisableInstrumentation() { |
| 1700 InstructionAccurateScope scope(this, 1); | 1700 InstructionAccurateScope scope(this, 1); |
| 1701 movn(xzr, InstrumentStateDisable); | 1701 movn(xzr, InstrumentStateDisable); |
| 1702 } | 1702 } |
| 1703 | 1703 |
| 1704 | 1704 |
| 1705 void MacroAssembler::AnnotateInstrumentation(const char* marker_name) { | 1705 void MacroAssembler::AnnotateInstrumentation(const char* marker_name) { |
| 1706 ASSERT(strlen(marker_name) == 2); | 1706 DCHECK(strlen(marker_name) == 2); |
| 1707 | 1707 |
| 1708 // We allow only printable characters in the marker names. Unprintable | 1708 // We allow only printable characters in the marker names. Unprintable |
| 1709 // characters are reserved for controlling features of the instrumentation. | 1709 // characters are reserved for controlling features of the instrumentation. |
| 1710 ASSERT(isprint(marker_name[0]) && isprint(marker_name[1])); | 1710 DCHECK(isprint(marker_name[0]) && isprint(marker_name[1])); |
| 1711 | 1711 |
| 1712 InstructionAccurateScope scope(this, 1); | 1712 InstructionAccurateScope scope(this, 1); |
| 1713 movn(xzr, (marker_name[1] << 8) | marker_name[0]); | 1713 movn(xzr, (marker_name[1] << 8) | marker_name[0]); |
| 1714 } | 1714 } |
| 1715 | 1715 |
| 1716 } } // namespace v8::internal | 1716 } } // namespace v8::internal |
| 1717 | 1717 |
| 1718 #endif // V8_ARM64_MACRO_ASSEMBLER_ARM64_INL_H_ | 1718 #endif // V8_ARM64_MACRO_ASSEMBLER_ARM64_INL_H_ |
| OLD | NEW |