| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef VM_ASSEMBLER_MIPS_H_ | 5 #ifndef VM_ASSEMBLER_MIPS_H_ |
| 6 #define VM_ASSEMBLER_MIPS_H_ | 6 #define VM_ASSEMBLER_MIPS_H_ |
| 7 | 7 |
| 8 #ifndef VM_ASSEMBLER_H_ | 8 #ifndef VM_ASSEMBLER_H_ |
| 9 #error Do not include assembler_mips.h directly; use assembler.h instead. | 9 #error Do not include assembler_mips.h directly; use assembler.h instead. |
| 10 #endif | 10 #endif |
| (...skipping 23 matching lines...) Expand all Loading... |
| 34 int32_t value_; | 34 int32_t value_; |
| 35 | 35 |
| 36 int32_t value() const { return value_; } | 36 int32_t value() const { return value_; } |
| 37 | 37 |
| 38 friend class Assembler; | 38 friend class Assembler; |
| 39 }; | 39 }; |
| 40 | 40 |
| 41 | 41 |
| 42 class Address : public ValueObject { | 42 class Address : public ValueObject { |
| 43 public: | 43 public: |
| 44 Address(Register base, int32_t offset) { | 44 Address(Register base, int32_t offset = 0) |
| 45 UNIMPLEMENTED(); | 45 : ValueObject(), base_(base), offset_(offset) { } |
| 46 } | |
| 47 | 46 |
| 48 Address(const Address& other) | 47 Address(const Address& other) |
| 49 : ValueObject(), base_(other.base_), offset_(other.offset_) { } | 48 : ValueObject(), base_(other.base_), offset_(other.offset_) { } |
| 50 Address& operator=(const Address& other) { | 49 Address& operator=(const Address& other) { |
| 51 base_ = other.base_; | 50 base_ = other.base_; |
| 52 offset_ = other.offset_; | 51 offset_ = other.offset_; |
| 53 return *this; | 52 return *this; |
| 54 } | 53 } |
| 55 | 54 |
| 55 uint32_t encoding() const { |
| 56 ASSERT(Utils::IsInt(16, offset_)); |
| 57 uint16_t imm_value = static_cast<uint16_t>(offset_); |
| 58 return (base_ << kRsShift) | imm_value; |
| 59 } |
| 60 |
| 56 private: | 61 private: |
| 57 Register base_; | 62 Register base_; |
| 58 int32_t offset_; | 63 int32_t offset_; |
| 59 }; | 64 }; |
| 60 | 65 |
| 61 | 66 |
| 62 class FieldAddress : public Address { | 67 class FieldAddress : public Address { |
| 63 public: | 68 public: |
| 64 FieldAddress(Register base, int32_t disp) | 69 FieldAddress(Register base, int32_t disp) |
| 65 : Address(base, disp - kHeapObjectTag) { } | 70 : Address(base, disp - kHeapObjectTag) { } |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 213 ASSERT(delay_slot_available_); | 218 ASSERT(delay_slot_available_); |
| 214 ASSERT(buffer_.Load<int32_t>(buffer_.GetPosition() - sizeof(int32_t)) == | 219 ASSERT(buffer_.Load<int32_t>(buffer_.GetPosition() - sizeof(int32_t)) == |
| 215 Instr::kNopInstruction); | 220 Instr::kNopInstruction); |
| 216 buffer_.Remit<int32_t>(); | 221 buffer_.Remit<int32_t>(); |
| 217 delay_slot_available_ = false; | 222 delay_slot_available_ = false; |
| 218 in_delay_slot_ = true; | 223 in_delay_slot_ = true; |
| 219 return this; | 224 return this; |
| 220 } | 225 } |
| 221 | 226 |
| 222 // CPU instructions. | 227 // CPU instructions. |
| 223 void addi(Register rt, Register rs, const Immediate& imm) { | |
| 224 ASSERT(Utils::IsUint(16, imm.value())); | |
| 225 uint16_t imm_value = static_cast<uint16_t>(imm.value()); | |
| 226 EmitIType(ADDI, rs, rt, imm_value); | |
| 227 } | |
| 228 | |
| 229 void addiu(Register rt, Register rs, const Immediate& imm) { | 228 void addiu(Register rt, Register rs, const Immediate& imm) { |
| 230 ASSERT(Utils::IsUint(16, imm.value())); | 229 ASSERT(Utils::IsInt(16, imm.value())); |
| 231 uint16_t imm_value = static_cast<uint16_t>(imm.value()); | 230 uint16_t imm_value = static_cast<uint16_t>(imm.value()); |
| 232 EmitIType(ADDIU, rs, rt, imm_value); | 231 EmitIType(ADDIU, rs, rt, imm_value); |
| 233 } | 232 } |
| 234 | 233 |
| 235 void addu(Register rd, Register rs, Register rt) { | 234 void addu(Register rd, Register rs, Register rt) { |
| 236 EmitRType(SPECIAL, rs, rt, rd, 0, ADDU); | 235 EmitRType(SPECIAL, rs, rt, rd, 0, ADDU); |
| 237 } | 236 } |
| 238 | 237 |
| 239 void and_(Register rd, Register rs, Register rt) { | 238 void and_(Register rd, Register rs, Register rt) { |
| 240 EmitRType(SPECIAL, rs, rt, rd, 0, AND); | 239 EmitRType(SPECIAL, rs, rt, rd, 0, AND); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 255 } | 254 } |
| 256 | 255 |
| 257 void div(Register rs, Register rt) { | 256 void div(Register rs, Register rt) { |
| 258 EmitRType(SPECIAL, rs, rt, R0, 0, DIV); | 257 EmitRType(SPECIAL, rs, rt, R0, 0, DIV); |
| 259 } | 258 } |
| 260 | 259 |
| 261 void divu(Register rs, Register rt) { | 260 void divu(Register rs, Register rt) { |
| 262 EmitRType(SPECIAL, rs, rt, R0, 0, DIVU); | 261 EmitRType(SPECIAL, rs, rt, R0, 0, DIVU); |
| 263 } | 262 } |
| 264 | 263 |
| 264 |
| 265 void lb(Register rt, const Address& addr) { |
| 266 EmitLoadStore(LB, rt, addr); |
| 267 } |
| 268 |
| 269 void lbu(Register rt, const Address& addr) { |
| 270 EmitLoadStore(LBU, rt, addr); |
| 271 } |
| 272 |
| 273 void lh(Register rt, const Address& addr) { |
| 274 EmitLoadStore(LH, rt, addr); |
| 275 } |
| 276 |
| 277 void lhu(Register rt, const Address& addr) { |
| 278 EmitLoadStore(LHU, rt, addr); |
| 279 } |
| 280 |
| 265 void lui(Register rt, const Immediate& imm) { | 281 void lui(Register rt, const Immediate& imm) { |
| 266 ASSERT(Utils::IsUint(16, imm.value())); | 282 ASSERT(Utils::IsUint(16, imm.value())); |
| 267 uint16_t imm_value = static_cast<uint16_t>(imm.value()); | 283 uint16_t imm_value = static_cast<uint16_t>(imm.value()); |
| 268 EmitIType(LUI, R0, rt, imm_value); | 284 EmitIType(LUI, R0, rt, imm_value); |
| 269 } | 285 } |
| 270 | 286 |
| 287 void lw(Register rt, const Address& addr) { |
| 288 EmitLoadStore(LW, rt, addr); |
| 289 } |
| 290 |
| 271 void mfhi(Register rd) { | 291 void mfhi(Register rd) { |
| 272 EmitRType(SPECIAL, R0, R0, rd, 0, MFHI); | 292 EmitRType(SPECIAL, R0, R0, rd, 0, MFHI); |
| 273 } | 293 } |
| 274 | 294 |
| 275 void mflo(Register rd) { | 295 void mflo(Register rd) { |
| 276 EmitRType(SPECIAL, R0, R0, rd, 0, MFLO); | 296 EmitRType(SPECIAL, R0, R0, rd, 0, MFLO); |
| 277 } | 297 } |
| 278 | 298 |
| 279 void ori(Register rt, Register rs, const Immediate& imm) { | 299 void ori(Register rt, Register rs, const Immediate& imm) { |
| 280 ASSERT(Utils::IsUint(16, imm.value())); | 300 ASSERT(Utils::IsUint(16, imm.value())); |
| 281 uint16_t imm_value = static_cast<uint16_t>(imm.value()); | 301 uint16_t imm_value = static_cast<uint16_t>(imm.value()); |
| 282 EmitIType(ORI, rs, rt, imm_value); | 302 EmitIType(ORI, rs, rt, imm_value); |
| 283 } | 303 } |
| 284 | 304 |
| 285 void jr(Register rs) { | 305 void jr(Register rs) { |
| 286 ASSERT(!in_delay_slot_); // Jump within a delay slot is not supported. | 306 ASSERT(!in_delay_slot_); // Jump within a delay slot is not supported. |
| 287 EmitRType(SPECIAL, rs, R0, R0, 0, JR); | 307 EmitRType(SPECIAL, rs, R0, R0, 0, JR); |
| 288 Emit(Instr::kNopInstruction); // Branch delay NOP. | 308 Emit(Instr::kNopInstruction); // Branch delay NOP. |
| 289 delay_slot_available_ = true; | 309 delay_slot_available_ = true; |
| 290 } | 310 } |
| 291 | 311 |
| 312 void sb(Register rt, const Address& addr) { |
| 313 EmitLoadStore(SB, rt, addr); |
| 314 } |
| 315 |
| 316 void sh(Register rt, const Address& addr) { |
| 317 EmitLoadStore(SH, rt, addr); |
| 318 } |
| 319 |
| 320 void sw(Register rt, const Address& addr) { |
| 321 EmitLoadStore(SW, rt, addr); |
| 322 } |
| 323 |
| 292 void sll(Register rd, Register rt, int sa) { | 324 void sll(Register rd, Register rt, int sa) { |
| 293 EmitRType(SPECIAL, R0, rt, rd, sa, SLL); | 325 EmitRType(SPECIAL, R0, rt, rd, sa, SLL); |
| 294 } | 326 } |
| 295 | 327 |
| 296 // Macros. | 328 // Macros. |
| 297 void LoadImmediate(Register rd, int32_t value) { | 329 void LoadImmediate(Register rd, int32_t value) { |
| 298 lui(rd, Immediate((value >> 16) & 0xffff)); | 330 lui(rd, Immediate((value >> 16) & 0xffff)); |
| 299 ori(rd, rd, Immediate(value & 0xffff)); | 331 ori(rd, rd, Immediate(value & 0xffff)); |
| 300 } | 332 } |
| 301 | 333 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 337 void EmitIType(Opcode opcode, | 369 void EmitIType(Opcode opcode, |
| 338 Register rs, | 370 Register rs, |
| 339 Register rt, | 371 Register rt, |
| 340 uint16_t imm) { | 372 uint16_t imm) { |
| 341 Emit(opcode << kOpcodeShift | | 373 Emit(opcode << kOpcodeShift | |
| 342 rs << kRsShift | | 374 rs << kRsShift | |
| 343 rt << kRtShift | | 375 rt << kRtShift | |
| 344 imm); | 376 imm); |
| 345 } | 377 } |
| 346 | 378 |
| 379 void EmitLoadStore(Opcode opcode, Register rt, |
| 380 const Address &addr) { |
| 381 Emit(opcode << kOpcodeShift | |
| 382 rt << kRtShift | |
| 383 addr.encoding()); |
| 384 } |
| 385 |
| 347 void EmitRegImmType(Opcode opcode, | 386 void EmitRegImmType(Opcode opcode, |
| 348 Register rs, | 387 Register rs, |
| 349 RtRegImm code, | 388 RtRegImm code, |
| 350 uint16_t imm) { | 389 uint16_t imm) { |
| 351 Emit(opcode << kOpcodeShift | | 390 Emit(opcode << kOpcodeShift | |
| 352 rs << kRsShift | | 391 rs << kRsShift | |
| 353 code << kRtShift | | 392 code << kRtShift | |
| 354 imm); | 393 imm); |
| 355 } | 394 } |
| 356 | 395 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 373 func << kFunctionShift); | 412 func << kFunctionShift); |
| 374 } | 413 } |
| 375 | 414 |
| 376 DISALLOW_ALLOCATION(); | 415 DISALLOW_ALLOCATION(); |
| 377 DISALLOW_COPY_AND_ASSIGN(Assembler); | 416 DISALLOW_COPY_AND_ASSIGN(Assembler); |
| 378 }; | 417 }; |
| 379 | 418 |
| 380 } // namespace dart | 419 } // namespace dart |
| 381 | 420 |
| 382 #endif // VM_ASSEMBLER_MIPS_H_ | 421 #endif // VM_ASSEMBLER_MIPS_H_ |
| OLD | NEW |