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

Side by Side Diff: src/trusted/validator_arm/inst_classes.cc

Issue 7799013: Intial Thumb2 Sandbox (naclrev 6680) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client
Patch Set: fix comma Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. 2 * Copyright (c) 2011 The Native Client Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be 3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file. 4 * found in the LICENSE file.
5 */ 5 */
6 6
7 #include "native_client/src/trusted/validator_arm/inst_classes.h" 7 #include "native_client/src/trusted/validator_arm/inst_classes.h"
8 8 // TODO(mrm) remove when debug is gone
bsy 2011/09/21 22:32:17 mrm
jasonwkim 2011/09/26 21:35:52 all mrm fixed
9 #include <stdio.h>
9 /* 10 /*
10 * Implementations of instruction classes, for those not completely defined in 11 * Implementations of instruction classes, for those not completely defined in
11 * the header. 12 * the header.
12 */ 13 */
13 14
14 namespace nacl_arm_dec { 15 namespace nacl_arm_dec {
15 16
16 /* 17 /*
17 * A utility function: given a modified-immediate-form instruction, extracts 18 * A utility function: given a modified-immediate-form instruction, extracts
18 * the immediate value. This is used to analyze BIC and TST. 19 * the immediate value. This is used to analyze BIC and TST.
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 RegisterList Branch::defs(const Instruction i) const { 413 RegisterList Branch::defs(const Instruction i) const {
413 return kRegisterPc + (i.bit(24)? kRegisterLink : kRegisterNone); 414 return kRegisterPc + (i.bit(24)? kRegisterLink : kRegisterNone);
414 } 415 }
415 416
416 int32_t Branch::branch_target_offset(const Instruction i) const { 417 int32_t Branch::branch_target_offset(const Instruction i) const {
417 // Sign extend and shift left 2: 418 // Sign extend and shift left 2:
418 int32_t offset = (int32_t)(i.bits(23, 0) << 8) >> 6; 419 int32_t offset = (int32_t)(i.bits(23, 0) << 8) >> 6;
419 return offset + 8; // because r15 reads as 8 bytes ahead 420 return offset + 8; // because r15 reads as 8 bytes ahead
420 } 421 }
421 422
423 /* Thumb Functions */
Karl 2011/09/19 19:56:05 Thumb2?
jasonwkim 2011/09/26 21:35:52 Thumb is more correct in this case
424 SafetyLevel Def3::safety(Instruction i) const {
425 /* If it tries to write to PC, unsafe */
426 if (defs(i)[kRegisterPc]) {
427 return FORBIDDEN_OPERANDS;
428 }
429 return MAY_BE_SAFE;
430 }
431
432 RegisterList Def3::defs(Instruction i) const {
433 return i.reg(3, 0);
434 }
435
436 SafetyLevel Def8_10::safety(Instruction i) const {
437 // TODO(mrm) should be encoding impossible, check
438 if (defs(i)[kRegisterPc]) {
439 return FORBIDDEN_OPERANDS;
440 }
441 return MAY_BE_SAFE;
442 }
443
444 RegisterList Def8_10::defs(Instruction i) const {
445 return i.reg(10, 8);
446 }
447
448 SafetyLevel MemOpThumb::safety(Instruction i) const {
449 // Don't let addressing writeback alter PC.
450 // TODO(mrm): Check if this is possible, we may be able to remove this.
451 if (defs(i)[kRegisterPc]) return FORBIDDEN_OPERANDS;
452
453 return MAY_BE_SAFE;
454 }
455
456 Register MemOpThumb::base_address_register(Instruction i) const {
457 return i.reg(5, 3);
458 }
459
460 RegisterList MemOpThumbLoad::defs(Instruction i) const {
461 return i.reg(2, 0);
462 }
463
464 // TODO(mrm) double check, this is suspect
465 // Specifically, double check if I need to +4 things?
466 int32_t CmpBrZ::branch_target_offset(Instruction i) const {
467 return int32_t ((i.bits(9, 9) << 6) & (i.bits(7, 3) << 1));
468 }
469
470 RegisterList PopMult::defs(Instruction i) const {
471 return RegisterList(i.bits(7, 0)) + kRegisterStack;
472 }
473
474 SafetyLevel BranchTCond::safety(Instruction i) const {
475 if ((condition(i) & 14) != 14)
476 return MAY_BE_SAFE;
477 return FORBIDDEN_OPERANDS;
478 }
479
480 // TODO(mrm) Check if I need to +4
481 int32_t BranchT1::branch_target_offset(Instruction i) const {
482 // Sign extend and left shift by one
483 return ((int32_t)(i.bits(7, 0) << 24)) >> 23;
484 }
485
486 // TODO(mrm) write test
487 Instruction::Condition BranchT1::condition(Instruction i) const {
488 return (Instruction::Condition)i.bits(11, 8);
489 }
490
491 // TODO(mrm) Check if I need to +4
492 int32_t BranchT2::branch_target_offset(Instruction i) const {
493 // Sign extend and left shift by one.
494 return ((int32_t)(i.bits(10, 0) << 21)) >> 20;
495 }
496
497 // TODO(mrm) Check if I need to +4
498 int32_t BranchT3::branch_target_offset(Instruction i) const {
499 // Construct the value
500 uint32_t val = ((((((((i.bit(10) << 1) | i.bit(27)) << 1) | i.bit(29)) << 6)
501 | i.bits(5, 0)) << 11) | i.bits(26, 16)) << 1;
502 // Sign extend it.
503 return ((int32_t)(val << 9)) >> 9;
504 }
505
506 Instruction::Condition BranchT3::condition(Instruction i) const {
507 return (Instruction::Condition)i.bits(9, 6);
508 }
509
510 int32_t get_stretched_immediate(Instruction i) {
511 uint32_t s = i.bit(10);
512 uint32_t i1 = (~(i.bit(27) ^ s)) & 1;
513 uint32_t i2 = (~(i.bit(29) ^ s)) & 1;
514 // Construct the value
515 uint32_t val = ((((((((i.bit(10) << 1) | i1) << 1) | i2) << 10)
516 | i.bits(9, 0)) << 11) | i.bits(26, 16)) << 1;
517 // Sign extend it, adjust for pc shift
518 return (((int32_t)(val << 9)) >> 9);
519 }
520
521 int32_t BranchT4::branch_target_offset(Instruction i) const {
522 return get_stretched_immediate(i) + 4;
523 }
524
525 // TODO(mrm) LDMT1/STMT1 could be cleaned up
526 RegisterList LDMT1::defs(Instruction i) const {
527 return RegisterList(i.bits(7, 0));
528 }
529
530 RegisterList STMT1::defs(Instruction i) const {
531 return RegisterList(i.bits(7, 0)) + i.reg(10, 8);
532 }
533
534 RegisterList STMT1::immediate_addressing_defs(Instruction i) const {
535 return i.reg(10, 8);
536 }
537
538 Register STMT1::base_address_register(Instruction i) const {
539 return i.reg(10, 8);
540 }
541
542 RegisterList LDRLitT1::defs(Instruction i) const {
543 return i.reg(10, 8);
544 }
545
546 RegisterList ADRT1::defs(Instruction i) const {
547 return i.reg(10, 8);
548 }
549
550 RegisterList MemOpSPThumbLoad::defs(Instruction i) const {
551 return i.reg(10, 8);
552 }
553
554 RegisterList DPMImm::defs(Instruction i) const {
555 return i.reg(27, 24);
556 }
557
558 uint32_t get_thumb_modified_immediate(Instruction i) {
559 uint32_t raw = i.bits(23, 16);
560 uint8_t shift_mode = (((i.bits(10, 10) << 3) | i.bits(30, 28)) << 1)
561 | i.bits(23, 23);
562 switch (shift_mode >> 1) {
563 case 0: return raw;
564 case 1: return (raw << 16) | raw;
565 case 2: return ((raw << 16) | raw) << 8;
566 case 3: return (((((raw << 8) | raw) << 8) | raw) << 8) | raw;
567 default: return (raw | (1 << 7)) << (31 - 7 - (shift_mode - 8));
568 };
569 }
570
571 bool BicModImmT::clears_bits(Instruction i, uint32_t mask) const {
572 return (get_thumb_modified_immediate(i) & mask) == mask;
573 }
574
575 bool OrrModImmT::sets_bits(Instruction i, uint32_t mask) const {
576 return get_thumb_modified_immediate(i) == mask;
577 }
578
579 RegisterList MovT::defs(Instruction i) const {
580 return Register((i.bits(7, 7) << 3) | i.bits(2, 0));
581 }
582
583 Register BXT::branch_target_register(Instruction i) const {
584 return i.reg(6, 3);
585 }
586
587 int32_t BLT::branch_target_offset(Instruction i) const {
588 return get_stretched_immediate(i);
589 }
590
591 ITCond IT::it_sequence(Instruction i) const {
592 uint8_t firstmask = i.bit(4);
593 ITCond base = it_set(0, THEN, 0);
594 uint8_t maskdex = 0;
595 while (i.bit(maskdex) == 0)
596 maskdex++;
597 // TODO(mrm) Add a guard to the parse table to make sure the mask is never 0
598 maskdex++;
599 for (uint8_t conddex = 1; maskdex < 4; maskdex++, conddex++) {
600 base = it_set(conddex, i.bit(maskdex) == firstmask ? THEN : ELSE, base);
601 }
602 return base;
603 }
604
605 Instruction::Condition IT::condition(Instruction i) const {
606 return (Instruction::Condition)i.bits(7, 4);
607 }
608
609 RegisterList STMTD::defs(Instruction i) const {
610 return i.reg(3, 0);
611 }
612
613 Register STMTD::base_address_register(Instruction i) const {
614 return i.reg(3, 0);
615 }
616
617 RegisterList STMTD::immediate_addressing_defs(Instruction i) const {
618 return base_address_register(i);
619 }
620
621 RegisterList LDMTD::defs(Instruction i) const {
622 return i.reg(3, 0) + RegisterList(i.bits(12, 0));
623 }
624
625 Register StrS::base_address_register(Instruction i) const {
626 return i.reg(3, 0);
627 }
628
629 // Note that while this doesn't always write something to i.reg(3, 0), it is
630 // safe to pretend that it does.
631 RegisterList StrS::defs(Instruction i) const {
632 return i.reg(3, 0);
633 }
634
635 Register LDRImmT3::base_address_register(Instruction i) const {
636 return i.reg(3, 0);
637 }
638
639 RegisterList LDRImmT4::defs(Instruction i) const {
640 if (i.bit(8 + 16)) {
641 return base_address_register(i); // Writeback
642 } else {
643 return kRegisterNone;
644 }
645 }
646
647 RegisterList LDRImmT4::immediate_addressing_defs(Instruction i) const {
648 return defs(i);
649 }
650
651 RegisterList Def31_18::defs(Instruction i) const {
652 return i.reg(31, 18);
653 }
654
655 RegisterList StrEx::defs(Instruction i) const {
656 return immediate_addressing_defs(i) + i.reg(11 + 16, 8 + 16);
657 }
658
659 RegisterList StrEx::immediate_addressing_defs(Instruction i) const {
660 if (i.bit(5))
661 return base_address_register(i);
662 return kRegisterNone;
663 }
664
665 Register StrEx::base_address_register(Instruction i) const {
666 return i.reg(3, 0);
667 }
668
669 RegisterList LdrEx::defs(Instruction i) const {
670 return immediate_addressing_defs(i) + i.reg(15 + 16, 12 + 16);
671 }
672
673 RegisterList StrD::defs(Instruction i) const {
674 return immediate_addressing_defs(i);
675 }
676
677 RegisterList LdrD::defs(Instruction i) const {
678 return immediate_addressing_defs(i) + i.reg(11 + 16, 8 + 16)
679 + i.reg(15 + 16, 12 + 16);
680 }
681
682 RegisterList Def27_24::defs(Instruction i) const {
683 return i.reg(27, 24);
684 }
685
686 bool ThumbBreakpoint::is_literal_pool_head(Instruction i) const {
687 UNREFERENCED_PARAMETER(i);
688 return true; //TODO We ideally want to think about conditions, but due to the
689 //rule that IT cannot straddle a boundary, and this has to start
690 //a bundle, we're fine.
691 }
692
422 } // namespace 693 } // namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698