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) { | 223 void addi(Register rt, Register rs, const Immediate& imm) { |
|
regis
2013/03/11 17:31:11
As discussed, we may never use this instruction, b
| |
| 224 ASSERT(Utils::IsUint(16, imm.value())); | 224 ASSERT(Utils::IsInt(16, imm.value())); |
| 225 uint16_t imm_value = static_cast<uint16_t>(imm.value()); | 225 uint16_t imm_value = static_cast<uint16_t>(imm.value()); |
| 226 EmitIType(ADDI, rs, rt, imm_value); | 226 EmitIType(ADDI, rs, rt, imm_value); |
| 227 } | 227 } |
| 228 | 228 |
| 229 void addiu(Register rt, Register rs, const Immediate& imm) { | 229 void addiu(Register rt, Register rs, const Immediate& imm) { |
| 230 ASSERT(Utils::IsUint(16, imm.value())); | 230 ASSERT(Utils::IsInt(16, imm.value())); |
| 231 uint16_t imm_value = static_cast<uint16_t>(imm.value()); | 231 uint16_t imm_value = static_cast<uint16_t>(imm.value()); |
| 232 EmitIType(ADDIU, rs, rt, imm_value); | 232 EmitIType(ADDIU, rs, rt, imm_value); |
| 233 } | 233 } |
| 234 | 234 |
| 235 void addu(Register rd, Register rs, Register rt) { | 235 void addu(Register rd, Register rs, Register rt) { |
| 236 EmitRType(SPECIAL, rs, rt, rd, 0, ADDU); | 236 EmitRType(SPECIAL, rs, rt, rd, 0, ADDU); |
| 237 } | 237 } |
| 238 | 238 |
| 239 void and_(Register rd, Register rs, Register rt) { | 239 void and_(Register rd, Register rs, Register rt) { |
| 240 EmitRType(SPECIAL, rs, rt, rd, 0, AND); | 240 EmitRType(SPECIAL, rs, rt, rd, 0, AND); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 255 } | 255 } |
| 256 | 256 |
| 257 void div(Register rs, Register rt) { | 257 void div(Register rs, Register rt) { |
| 258 EmitRType(SPECIAL, rs, rt, R0, 0, DIV); | 258 EmitRType(SPECIAL, rs, rt, R0, 0, DIV); |
| 259 } | 259 } |
| 260 | 260 |
| 261 void divu(Register rs, Register rt) { | 261 void divu(Register rs, Register rt) { |
| 262 EmitRType(SPECIAL, rs, rt, R0, 0, DIVU); | 262 EmitRType(SPECIAL, rs, rt, R0, 0, DIVU); |
| 263 } | 263 } |
| 264 | 264 |
| 265 // Extract bit field. | |
| 266 void ext(Register rt, Register rs, int32_t pos, int32_t size) { | |
| 267 ASSERT((0 <= pos) && (pos < 32)); | |
| 268 ASSERT((0 < size) && (size <= 32)); | |
| 269 ASSERT((0 < pos + size) && (pos + size <= 32)); | |
|
regis
2013/03/11 17:31:11
You could express these 3 asserts using Utils::IsU
| |
| 270 EmitRType(SPECIAL3, rs, rt, static_cast<Register>(size - 1), pos, EXT); | |
|
Ivan Posva
2013/03/11 17:29:04
Maybe we should have a EmitRType which takes a int
| |
| 271 } | |
| 272 | |
| 273 // Insert bit field. | |
| 274 void ins(Register rt, Register rs, int32_t pos, int32_t size) { | |
| 275 ASSERT((0 <= pos) && (pos < 32)); | |
| 276 ASSERT((0 < size) && (size <= 32)); | |
| 277 ASSERT((0 < pos + size) && (pos + size <= 32)); | |
|
regis
2013/03/11 17:31:11
ditto
Btw, I am not sure we are going to use ext
zra
2013/03/11 18:36:06
If these won't be used, as with addi, I'd be happy
zra
2013/03/11 20:00:11
As discussed, I have removed ext and ins.
| |
| 278 EmitRType(SPECIAL3, rs, rt, | |
| 279 static_cast<Register>(pos + size - 1), pos, INS); | |
| 280 } | |
| 281 | |
| 282 void lb(Register rt, const Immediate& off, Register base) { | |
|
Ivan Posva
2013/03/11 17:29:04
The correct parameters here should be
void lb(Regi
zra
2013/03/11 18:36:06
As far as I understand, the addressing modes in MI
| |
| 283 ASSERT(Utils::IsInt(16, off.value())); | |
| 284 uint16_t off_value = static_cast<uint16_t>(off.value()); | |
| 285 EmitIType(LB, base, rt, off_value); | |
| 286 } | |
| 287 | |
| 288 void lbu(Register rt, const Immediate& off, Register base) { | |
| 289 ASSERT(Utils::IsInt(16, off.value())); | |
| 290 uint16_t off_value = static_cast<uint16_t>(off.value()); | |
| 291 EmitIType(LBU, base, rt, off_value); | |
| 292 } | |
| 293 | |
| 294 void lh(Register rt, const Immediate& off, Register base) { | |
| 295 ASSERT(Utils::IsInt(16, off.value())); | |
| 296 uint16_t off_value = static_cast<uint16_t>(off.value()); | |
| 297 EmitIType(LH, base, rt, off_value); | |
| 298 } | |
| 299 | |
| 300 void lhu(Register rt, const Immediate& off, Register base) { | |
| 301 ASSERT(Utils::IsInt(16, off.value())); | |
| 302 uint16_t off_value = static_cast<uint16_t>(off.value()); | |
| 303 EmitIType(LHU, base, rt, off_value); | |
| 304 } | |
| 305 | |
| 265 void lui(Register rt, const Immediate& imm) { | 306 void lui(Register rt, const Immediate& imm) { |
| 266 ASSERT(Utils::IsUint(16, imm.value())); | 307 ASSERT(Utils::IsUint(16, imm.value())); |
| 267 uint16_t imm_value = static_cast<uint16_t>(imm.value()); | 308 uint16_t imm_value = static_cast<uint16_t>(imm.value()); |
| 268 EmitIType(LUI, R0, rt, imm_value); | 309 EmitIType(LUI, R0, rt, imm_value); |
| 269 } | 310 } |
| 270 | 311 |
| 312 void lw(Register rt, const Immediate& off, Register base) { | |
| 313 ASSERT(Utils::IsInt(16, off.value())); | |
| 314 uint16_t off_value = static_cast<uint16_t>(off.value()); | |
| 315 EmitIType(LW, base, rt, off_value); | |
| 316 } | |
| 317 | |
| 271 void mfhi(Register rd) { | 318 void mfhi(Register rd) { |
| 272 EmitRType(SPECIAL, R0, R0, rd, 0, MFHI); | 319 EmitRType(SPECIAL, R0, R0, rd, 0, MFHI); |
| 273 } | 320 } |
| 274 | 321 |
| 275 void mflo(Register rd) { | 322 void mflo(Register rd) { |
| 276 EmitRType(SPECIAL, R0, R0, rd, 0, MFLO); | 323 EmitRType(SPECIAL, R0, R0, rd, 0, MFLO); |
| 277 } | 324 } |
| 278 | 325 |
| 279 void ori(Register rt, Register rs, const Immediate& imm) { | 326 void ori(Register rt, Register rs, const Immediate& imm) { |
| 280 ASSERT(Utils::IsUint(16, imm.value())); | 327 ASSERT(Utils::IsUint(16, imm.value())); |
| 281 uint16_t imm_value = static_cast<uint16_t>(imm.value()); | 328 uint16_t imm_value = static_cast<uint16_t>(imm.value()); |
| 282 EmitIType(ORI, rs, rt, imm_value); | 329 EmitIType(ORI, rs, rt, imm_value); |
| 283 } | 330 } |
| 284 | 331 |
| 285 void jr(Register rs) { | 332 void jr(Register rs) { |
| 286 ASSERT(!in_delay_slot_); // Jump within a delay slot is not supported. | 333 ASSERT(!in_delay_slot_); // Jump within a delay slot is not supported. |
| 287 EmitRType(SPECIAL, rs, R0, R0, 0, JR); | 334 EmitRType(SPECIAL, rs, R0, R0, 0, JR); |
| 288 Emit(Instr::kNopInstruction); // Branch delay NOP. | 335 Emit(Instr::kNopInstruction); // Branch delay NOP. |
| 289 delay_slot_available_ = true; | 336 delay_slot_available_ = true; |
| 290 } | 337 } |
| 291 | 338 |
| 339 void sb(Register rt, const Immediate& off, Register base) { | |
|
Ivan Posva
2013/03/11 17:29:04
ditto.
| |
| 340 ASSERT(Utils::IsInt(16, off.value())); | |
| 341 uint16_t off_value = static_cast<uint16_t>(off.value()); | |
| 342 EmitIType(SB, base, rt, off_value); | |
| 343 } | |
| 344 | |
| 345 void sh(Register rt, const Immediate& off, Register base) { | |
| 346 ASSERT(Utils::IsInt(16, off.value())); | |
| 347 uint16_t off_value = static_cast<uint16_t>(off.value()); | |
| 348 EmitIType(SH, base, rt, off_value); | |
| 349 } | |
| 350 | |
| 351 void sw(Register rt, const Immediate& off, Register base) { | |
| 352 ASSERT(Utils::IsInt(16, off.value())); | |
| 353 uint16_t off_value = static_cast<uint16_t>(off.value()); | |
| 354 EmitIType(SW, base, rt, off_value); | |
| 355 } | |
| 356 | |
| 292 void sll(Register rd, Register rt, int sa) { | 357 void sll(Register rd, Register rt, int sa) { |
| 293 EmitRType(SPECIAL, R0, rt, rd, sa, SLL); | 358 EmitRType(SPECIAL, R0, rt, rd, sa, SLL); |
| 294 } | 359 } |
| 295 | 360 |
| 296 // Macros. | 361 // Macros. |
| 297 void LoadImmediate(Register rd, int32_t value) { | 362 void LoadImmediate(Register rd, int32_t value) { |
| 298 lui(rd, Immediate((value >> 16) & 0xffff)); | 363 lui(rd, Immediate((value >> 16) & 0xffff)); |
| 299 ori(rd, rd, Immediate(value & 0xffff)); | 364 ori(rd, rd, Immediate(value & 0xffff)); |
| 300 } | 365 } |
| 301 | 366 |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 373 func << kFunctionShift); | 438 func << kFunctionShift); |
| 374 } | 439 } |
| 375 | 440 |
| 376 DISALLOW_ALLOCATION(); | 441 DISALLOW_ALLOCATION(); |
| 377 DISALLOW_COPY_AND_ASSIGN(Assembler); | 442 DISALLOW_COPY_AND_ASSIGN(Assembler); |
| 378 }; | 443 }; |
| 379 | 444 |
| 380 } // namespace dart | 445 } // namespace dart |
| 381 | 446 |
| 382 #endif // VM_ASSEMBLER_MIPS_H_ | 447 #endif // VM_ASSEMBLER_MIPS_H_ |
| OLD | NEW |