Chromium Code Reviews| 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 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 213 ASSERT(delay_slot_available_); | 213 ASSERT(delay_slot_available_); |
| 214 ASSERT(buffer_.Load<int32_t>(buffer_.GetPosition() - sizeof(int32_t)) == | 214 ASSERT(buffer_.Load<int32_t>(buffer_.GetPosition() - sizeof(int32_t)) == |
| 215 Instr::kNopInstruction); | 215 Instr::kNopInstruction); |
| 216 buffer_.Remit<int32_t>(); | 216 buffer_.Remit<int32_t>(); |
| 217 delay_slot_available_ = false; | 217 delay_slot_available_ = false; |
| 218 in_delay_slot_ = true; | 218 in_delay_slot_ = true; |
| 219 return this; | 219 return this; |
| 220 } | 220 } |
| 221 | 221 |
| 222 // CPU instructions. | 222 // 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) { | |
| 230 ASSERT(Utils::IsUint(16, imm.value())); | |
| 231 uint16_t imm_value = static_cast<uint16_t>(imm.value()); | |
| 232 EmitIType(ADDIU, rs, rt, imm_value); | |
| 233 } | |
| 234 | |
| 235 void addu(Register rd, Register rs, Register rt) { | |
| 236 EmitRType(SPECIAL, rs, rt, rd, 0, ADDU); | |
| 237 } | |
| 238 | |
| 239 void and_(Register rd, Register rs, Register rt) { | |
| 240 EmitRType(SPECIAL, rs, rt, rd, 0, AND); | |
| 241 } | |
| 242 | |
| 243 void andi(Register rt, Register rs, const Immediate& imm) { | |
| 244 ASSERT(Utils::IsUint(16, imm.value())); | |
| 245 uint16_t imm_value = static_cast<uint16_t>(imm.value()); | |
| 246 EmitIType(ANDI, rs, rt, imm_value); | |
| 247 } | |
| 248 | |
| 249 void clo(Register rd, Register rs) { | |
| 250 EmitRType(SPECIAL2, rs, rd, rd, 0, CLO); | |
| 251 } | |
| 252 | |
| 253 void clz(Register rd, Register rs) { | |
| 254 EmitRType(SPECIAL2, rs, rd, rd, 0, CLZ); | |
| 255 } | |
| 256 | |
| 257 void div(Register rs, Register rt) { | |
| 258 EmitRType(SPECIAL, rs, rt, R0, 0, DIV); | |
| 259 } | |
| 260 | |
| 261 void divu(Register rs, Register rt) { | |
| 262 EmitRType(SPECIAL, rs, rt, R0, 0, DIVU); | |
| 263 } | |
| 264 | |
| 265 void mfhi(Register rd) { | |
| 266 EmitRType(SPECIAL, R0, R0, rd, 0, MFHI); | |
| 267 } | |
| 268 | |
| 269 void mflo(Register rd) { | |
| 270 EmitRType(SPECIAL, R0, R0, rd, 0, MFLO); | |
| 271 } | |
| 272 | |
| 223 void ori(Register rt, Register rs, const Immediate& imm) { | 273 void ori(Register rt, Register rs, const Immediate& imm) { |
| 224 ASSERT(Utils::IsUint(16, imm.value())); | 274 ASSERT(Utils::IsUint(16, imm.value())); |
| 225 uint16_t imm_value = static_cast<uint16_t>(imm.value()); | 275 uint16_t imm_value = static_cast<uint16_t>(imm.value()); |
| 226 EmitIType(ORI, rs, rt, imm_value); | 276 EmitIType(ORI, rs, rt, imm_value); |
| 227 } | 277 } |
| 228 | 278 |
| 229 void jr(Register rs) { | 279 void jr(Register rs) { |
| 230 ASSERT(!in_delay_slot_); // Jump within a delay slot is not supported. | 280 ASSERT(!in_delay_slot_); // Jump within a delay slot is not supported. |
| 231 EmitRType(SPECIAL, rs, R0, R0, 0, JR); | 281 EmitRType(SPECIAL, rs, R0, R0, 0, JR); |
| 232 Emit(Instr::kNopInstruction); // Branch delay NOP. | 282 Emit(Instr::kNopInstruction); // Branch delay NOP. |
| 233 delay_slot_available_ = true; | 283 delay_slot_available_ = true; |
| 234 } | 284 } |
| 235 | 285 |
| 286 void sll(Register rd, Register rt, int sa) { | |
| 287 EmitRType(SPECIAL, R0, rt, rd, sa, SLL); | |
| 288 } | |
| 289 | |
| 290 // Macros. | |
| 291 void LoadImmediate(Register rd, int32_t value) { | |
| 292 addi(rd, R0, Immediate((value >> 16) & 0xffff)); | |
| 293 sll(rd, rd, 16); | |
|
regis
2013/03/08 21:09:03
The 2 instructions above can be replaced by a sing
| |
| 294 ori(rd, rd, Immediate(value & 0xffff)); | |
| 295 } | |
| 296 | |
| 236 private: | 297 private: |
| 237 AssemblerBuffer buffer_; | 298 AssemblerBuffer buffer_; |
| 238 GrowableObjectArray& object_pool_; // Objects and patchable jump targets. | 299 GrowableObjectArray& object_pool_; // Objects and patchable jump targets. |
| 239 int prologue_offset_; | 300 int prologue_offset_; |
| 240 | 301 |
| 241 bool delay_slot_available_; | 302 bool delay_slot_available_; |
| 242 bool in_delay_slot_; | 303 bool in_delay_slot_; |
| 243 | 304 |
| 244 class CodeComment : public ZoneAllocated { | 305 class CodeComment : public ZoneAllocated { |
| 245 public: | 306 public: |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 271 void EmitIType(Opcode opcode, | 332 void EmitIType(Opcode opcode, |
| 272 Register rs, | 333 Register rs, |
| 273 Register rt, | 334 Register rt, |
| 274 uint16_t imm) { | 335 uint16_t imm) { |
| 275 Emit(opcode << kOpcodeShift | | 336 Emit(opcode << kOpcodeShift | |
| 276 rs << kRsShift | | 337 rs << kRsShift | |
| 277 rt << kRtShift | | 338 rt << kRtShift | |
| 278 imm); | 339 imm); |
| 279 } | 340 } |
| 280 | 341 |
| 342 void EmitRegImmType(Opcode opcode, | |
| 343 Register rs, | |
| 344 RtRegImm code, | |
| 345 uint16_t imm) { | |
| 346 Emit(opcode << kOpcodeShift | | |
| 347 rs << kRsShift | | |
| 348 code << kRtShift | | |
| 349 imm); | |
| 350 } | |
| 351 | |
| 281 void EmitJType(Opcode opcode, Label* label) { | 352 void EmitJType(Opcode opcode, Label* label) { |
| 282 UNIMPLEMENTED(); | 353 UNIMPLEMENTED(); |
| 283 } | 354 } |
| 284 | 355 |
| 285 void EmitRType(Opcode opcode, | 356 void EmitRType(Opcode opcode, |
| 286 Register rs, | 357 Register rs, |
| 287 Register rt, | 358 Register rt, |
| 288 Register rd, | 359 Register rd, |
| 289 int sa, | 360 int sa, |
| 290 SpecialFunction func) { | 361 SpecialFunction func) { |
| 291 ASSERT(Utils::IsUint(5, sa)); | 362 ASSERT(Utils::IsUint(5, sa)); |
| 292 Emit(opcode << kOpcodeShift | | 363 Emit(opcode << kOpcodeShift | |
| 293 rs << kRsShift | | 364 rs << kRsShift | |
| 294 rt << kRtShift | | 365 rt << kRtShift | |
| 295 rd << kRdShift | | 366 rd << kRdShift | |
| 296 sa << kSaShift | | 367 sa << kSaShift | |
| 297 func << kFunctionShift); | 368 func << kFunctionShift); |
| 298 } | 369 } |
| 299 | 370 |
| 300 DISALLOW_ALLOCATION(); | 371 DISALLOW_ALLOCATION(); |
| 301 DISALLOW_COPY_AND_ASSIGN(Assembler); | 372 DISALLOW_COPY_AND_ASSIGN(Assembler); |
| 302 }; | 373 }; |
| 303 | 374 |
| 304 } // namespace dart | 375 } // namespace dart |
| 305 | 376 |
| 306 #endif // VM_ASSEMBLER_MIPS_H_ | 377 #endif // VM_ASSEMBLER_MIPS_H_ |
| OLD | NEW |