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

Side by Side Diff: src/IceAssemblerX86BaseImpl.h

Issue 1257283004: Iasm and obj lowering for advanced switch lowering. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Created 5 years, 4 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
OLDNEW
1 //===- subzero/src/IceAssemblerX86BaseImpl.h - base x86 assembler -*- C++ -*-=// 1 //===- subzero/src/IceAssemblerX86BaseImpl.h - base x86 assembler -*- C++ -*-=//
2 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 2 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
3 // for details. All rights reserved. Use of this source code is governed by a 3 // for details. All rights reserved. Use of this source code is governed by a
4 // BSD-style license that can be found in the LICENSE file. 4 // BSD-style license that can be found in the LICENSE file.
5 // 5 //
6 // Modified by the Subzero authors. 6 // Modified by the Subzero authors.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 // 9 //
10 // The Subzero Code Generator 10 // The Subzero Code Generator
(...skipping 13 matching lines...) Expand all
24 #include "IceCfg.h" 24 #include "IceCfg.h"
25 #include "IceOperand.h" 25 #include "IceOperand.h"
26 26
27 namespace Ice { 27 namespace Ice {
28 namespace X86Internal { 28 namespace X86Internal {
29 29
30 template <class Machine> 30 template <class Machine>
31 AssemblerX86Base<Machine>::~AssemblerX86Base<Machine>() { 31 AssemblerX86Base<Machine>::~AssemblerX86Base<Machine>() {
32 if (BuildDefs::asserts()) { 32 if (BuildDefs::asserts()) {
33 for (const Label *Label : CfgNodeLabels) { 33 for (const Label *Label : CfgNodeLabels) {
34 Label->FinalCheck(); 34 Label->finalCheck();
35 } 35 }
36 for (const Label *Label : LocalLabels) { 36 for (const Label *Label : LocalLabels) {
37 Label->FinalCheck(); 37 Label->finalCheck();
38 } 38 }
39 } 39 }
40 } 40 }
41 41
42 template <class Machine> void AssemblerX86Base<Machine>::alignFunction() { 42 template <class Machine> void AssemblerX86Base<Machine>::alignFunction() {
43 SizeT Align = 1 << getBundleAlignLog2Bytes(); 43 const SizeT Align = 1 << getBundleAlignLog2Bytes();
44 SizeT BytesNeeded = Utils::OffsetToAlignment(Buffer.getPosition(), Align); 44 SizeT BytesNeeded = Utils::OffsetToAlignment(Buffer.getPosition(), Align);
45 const SizeT HltSize = 1; 45 constexpr SizeT HltSize = 1;
46 while (BytesNeeded > 0) { 46 while (BytesNeeded > 0) {
47 hlt(); 47 hlt();
48 BytesNeeded -= HltSize; 48 BytesNeeded -= HltSize;
49 } 49 }
50 } 50 }
51 51
52 template <class Machine> void AssemblerX86Base<Machine>::alignCfgNode() {
53 const SizeT Align = 1 << getBundleAlignLog2Bytes();
54 padWithNop(Utils::OffsetToAlignment(Buffer.getPosition(), Align));
55 }
56
52 template <class Machine> 57 template <class Machine>
53 Label *AssemblerX86Base<Machine>::GetOrCreateLabel(SizeT Number, 58 Label *AssemblerX86Base<Machine>::getOrCreateLabel(SizeT Number,
54 LabelVector &Labels) { 59 LabelVector &Labels) {
55 Label *L = nullptr; 60 Label *L = nullptr;
56 if (Number == Labels.size()) { 61 if (Number == Labels.size()) {
57 L = new (this->allocate<Label>()) Label(); 62 L = new (this->allocate<Label>()) Label();
58 Labels.push_back(L); 63 Labels.push_back(L);
59 return L; 64 return L;
60 } 65 }
61 if (Number > Labels.size()) { 66 if (Number > Labels.size()) {
62 Labels.resize(Number + 1); 67 Labels.resize(Number + 1);
63 } 68 }
64 L = Labels[Number]; 69 L = Labels[Number];
65 if (!L) { 70 if (!L) {
66 L = new (this->allocate<Label>()) Label(); 71 L = new (this->allocate<Label>()) Label();
67 Labels[Number] = L; 72 Labels[Number] = L;
68 } 73 }
69 return L; 74 return L;
70 } 75 }
71 76
72 template <class Machine> 77 template <class Machine>
73 Label *AssemblerX86Base<Machine>::GetOrCreateCfgNodeLabel(SizeT NodeNumber) { 78 Label *AssemblerX86Base<Machine>::getOrCreateCfgNodeLabel(SizeT NodeNumber) {
74 return GetOrCreateLabel(NodeNumber, CfgNodeLabels); 79 return getOrCreateLabel(NodeNumber, CfgNodeLabels);
75 } 80 }
76 81
77 template <class Machine> 82 template <class Machine>
78 Label *AssemblerX86Base<Machine>::GetOrCreateLocalLabel(SizeT Number) { 83 Label *AssemblerX86Base<Machine>::getOrCreateLocalLabel(SizeT Number) {
79 return GetOrCreateLabel(Number, LocalLabels); 84 return getOrCreateLabel(Number, LocalLabels);
80 } 85 }
81 86
82 template <class Machine> 87 template <class Machine>
83 void AssemblerX86Base<Machine>::bindCfgNodeLabel(SizeT NodeNumber) { 88 void AssemblerX86Base<Machine>::bindCfgNodeLabel(SizeT NodeNumber) {
84 assert(!getPreliminary()); 89 assert(!getPreliminary());
85 Label *L = GetOrCreateCfgNodeLabel(NodeNumber); 90 Label *L = getOrCreateCfgNodeLabel(NodeNumber);
86 this->bind(L); 91 this->bind(L);
87 } 92 }
88 93
89 template <class Machine> 94 template <class Machine>
90 void AssemblerX86Base<Machine>::BindLocalLabel(SizeT Number) { 95 void AssemblerX86Base<Machine>::BindLocalLabel(SizeT Number) {
91 Label *L = GetOrCreateLocalLabel(Number); 96 Label *L = getOrCreateLocalLabel(Number);
92 if (!getPreliminary()) 97 if (!getPreliminary())
93 this->bind(L); 98 this->bind(L);
94 } 99 }
95 100
96 template <class Machine> 101 template <class Machine>
97 void AssemblerX86Base<Machine>::call(typename Traits::GPRRegister reg) { 102 void AssemblerX86Base<Machine>::call(typename Traits::GPRRegister reg) {
98 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 103 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
99 emitUint8(0xFF); 104 emitUint8(0xFF);
100 emitRegisterOperand(2, reg); 105 emitRegisterOperand(2, reg);
101 } 106 }
(...skipping 2671 matching lines...) Expand 10 before | Expand all | Expand 10 after
2773 template <class Machine> void AssemblerX86Base<Machine>::ud2() { 2778 template <class Machine> void AssemblerX86Base<Machine>::ud2() {
2774 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2779 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2775 emitUint8(0x0F); 2780 emitUint8(0x0F);
2776 emitUint8(0x0B); 2781 emitUint8(0x0B);
2777 } 2782 }
2778 2783
2779 template <class Machine> 2784 template <class Machine>
2780 void AssemblerX86Base<Machine>::j(typename Traits::Cond::BrCond condition, 2785 void AssemblerX86Base<Machine>::j(typename Traits::Cond::BrCond condition,
2781 Label *label, bool near) { 2786 Label *label, bool near) {
2782 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2787 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2783 if (label->IsBound()) { 2788 if (label->isBound()) {
2784 static const int kShortSize = 2; 2789 static const int kShortSize = 2;
2785 static const int kLongSize = 6; 2790 static const int kLongSize = 6;
2786 intptr_t offset = label->Position() - Buffer.size(); 2791 intptr_t offset = label->getPosition() - Buffer.size();
2787 assert(offset <= 0); 2792 assert(offset <= 0);
2788 if (Utils::IsInt(8, offset - kShortSize)) { 2793 if (Utils::IsInt(8, offset - kShortSize)) {
2789 // TODO(stichnot): Here and in jmp(), we may need to be more 2794 // TODO(stichnot): Here and in jmp(), we may need to be more
2790 // conservative about the backward branch distance if the branch 2795 // conservative about the backward branch distance if the branch
2791 // instruction is within a bundle_lock sequence, because the 2796 // instruction is within a bundle_lock sequence, because the
2792 // distance may increase when padding is added. This isn't an 2797 // distance may increase when padding is added. This isn't an
2793 // issue for branches outside a bundle_lock, because if padding 2798 // issue for branches outside a bundle_lock, because if padding
2794 // is added, the retry may change it to a long backward branch 2799 // is added, the retry may change it to a long backward branch
2795 // without affecting any of the bookkeeping. 2800 // without affecting any of the bookkeeping.
2796 emitUint8(0x70 + condition); 2801 emitUint8(0x70 + condition);
(...skipping 26 matching lines...) Expand all
2823 template <class Machine> 2828 template <class Machine>
2824 void AssemblerX86Base<Machine>::jmp(typename Traits::GPRRegister reg) { 2829 void AssemblerX86Base<Machine>::jmp(typename Traits::GPRRegister reg) {
2825 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2830 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2826 emitUint8(0xFF); 2831 emitUint8(0xFF);
2827 emitRegisterOperand(4, reg); 2832 emitRegisterOperand(4, reg);
2828 } 2833 }
2829 2834
2830 template <class Machine> 2835 template <class Machine>
2831 void AssemblerX86Base<Machine>::jmp(Label *label, bool near) { 2836 void AssemblerX86Base<Machine>::jmp(Label *label, bool near) {
2832 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2837 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2833 if (label->IsBound()) { 2838 if (label->isBound()) {
2834 static const int kShortSize = 2; 2839 static const int kShortSize = 2;
2835 static const int kLongSize = 5; 2840 static const int kLongSize = 5;
2836 intptr_t offset = label->Position() - Buffer.size(); 2841 intptr_t offset = label->getPosition() - Buffer.size();
2837 assert(offset <= 0); 2842 assert(offset <= 0);
2838 if (Utils::IsInt(8, offset - kShortSize)) { 2843 if (Utils::IsInt(8, offset - kShortSize)) {
2839 emitUint8(0xEB); 2844 emitUint8(0xEB);
2840 emitUint8((offset - kShortSize) & 0xFF); 2845 emitUint8((offset - kShortSize) & 0xFF);
2841 } else { 2846 } else {
2842 emitUint8(0xE9); 2847 emitUint8(0xE9);
2843 emitInt32(offset - kLongSize); 2848 emitInt32(offset - kLongSize);
2844 } 2849 }
2845 } else if (near) { 2850 } else if (near) {
2846 emitUint8(0xEB); 2851 emitUint8(0xEB);
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
2952 bytes_needed -= MAX_NOP_SIZE; 2957 bytes_needed -= MAX_NOP_SIZE;
2953 } 2958 }
2954 if (bytes_needed) { 2959 if (bytes_needed) {
2955 nop(bytes_needed); 2960 nop(bytes_needed);
2956 } 2961 }
2957 assert(((offset + Buffer.getPosition()) & (alignment - 1)) == 0); 2962 assert(((offset + Buffer.getPosition()) & (alignment - 1)) == 0);
2958 } 2963 }
2959 2964
2960 template <class Machine> void AssemblerX86Base<Machine>::bind(Label *label) { 2965 template <class Machine> void AssemblerX86Base<Machine>::bind(Label *label) {
2961 intptr_t bound = Buffer.size(); 2966 intptr_t bound = Buffer.size();
2962 assert(!label->IsBound()); // Labels can only be bound once. 2967 assert(!label->isBound()); // Labels can only be bound once.
2963 while (label->IsLinked()) { 2968 while (label->isLinked()) {
2964 intptr_t position = label->LinkPosition(); 2969 intptr_t position = label->getLinkPosition();
2965 intptr_t next = Buffer.load<int32_t>(position); 2970 intptr_t next = Buffer.load<int32_t>(position);
2966 Buffer.store<int32_t>(position, bound - (position + 4)); 2971 Buffer.store<int32_t>(position, bound - (position + 4));
2967 label->position_ = next; 2972 label->Position = next;
2968 } 2973 }
2969 while (label->HasNear()) { 2974 while (label->hasNear()) {
2970 intptr_t position = label->NearPosition(); 2975 intptr_t position = label->getNearPosition();
2971 intptr_t offset = bound - (position + 1); 2976 intptr_t offset = bound - (position + 1);
2972 assert(Utils::IsInt(8, offset)); 2977 assert(Utils::IsInt(8, offset));
2973 Buffer.store<int8_t>(position, offset); 2978 Buffer.store<int8_t>(position, offset);
2974 } 2979 }
2975 label->BindTo(bound); 2980 label->bindTo(bound);
2976 } 2981 }
2977 2982
2978 template <class Machine> 2983 template <class Machine>
2979 void AssemblerX86Base<Machine>::emitOperand( 2984 void AssemblerX86Base<Machine>::emitOperand(
2980 int rm, const typename Traits::Operand &operand) { 2985 int rm, const typename Traits::Operand &operand) {
2981 assert(rm >= 0 && rm < 8); 2986 assert(rm >= 0 && rm < 8);
2982 const intptr_t length = operand.length_; 2987 const intptr_t length = operand.length_;
2983 assert(length > 0); 2988 assert(length > 0);
2984 // Emit the ModRM byte updated with the given RM value. 2989 // Emit the ModRM byte updated with the given RM value.
2985 assert((operand.encoding_[0] & 0x38) == 0); 2990 assert((operand.encoding_[0] & 0x38) == 0);
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
3041 } else { 3046 } else {
3042 emitUint8(0x81); 3047 emitUint8(0x81);
3043 emitOperand(rm, operand); 3048 emitOperand(rm, operand);
3044 emitImmediate(Ty, immediate); 3049 emitImmediate(Ty, immediate);
3045 } 3050 }
3046 } 3051 }
3047 3052
3048 template <class Machine> 3053 template <class Machine>
3049 void AssemblerX86Base<Machine>::emitLabel(Label *label, 3054 void AssemblerX86Base<Machine>::emitLabel(Label *label,
3050 intptr_t instruction_size) { 3055 intptr_t instruction_size) {
3051 if (label->IsBound()) { 3056 if (label->isBound()) {
3052 intptr_t offset = label->Position() - Buffer.size(); 3057 intptr_t offset = label->getPosition() - Buffer.size();
3053 assert(offset <= 0); 3058 assert(offset <= 0);
3054 emitInt32(offset - instruction_size); 3059 emitInt32(offset - instruction_size);
3055 } else { 3060 } else {
3056 emitLabelLink(label); 3061 emitLabelLink(label);
3057 } 3062 }
3058 } 3063 }
3059 3064
3060 template <class Machine> 3065 template <class Machine>
3061 void AssemblerX86Base<Machine>::emitLabelLink(Label *Label) { 3066 void AssemblerX86Base<Machine>::emitLabelLink(Label *Label) {
3062 assert(!Label->IsBound()); 3067 assert(!Label->isBound());
3063 intptr_t Position = Buffer.size(); 3068 intptr_t Position = Buffer.size();
3064 emitInt32(Label->position_); 3069 emitInt32(Label->Position);
3065 if (!getPreliminary()) 3070 if (!getPreliminary())
3066 Label->LinkTo(Position); 3071 Label->linkTo(Position);
3067 } 3072 }
3068 3073
3069 template <class Machine> 3074 template <class Machine>
3070 void AssemblerX86Base<Machine>::emitNearLabelLink(Label *label) { 3075 void AssemblerX86Base<Machine>::emitNearLabelLink(Label *label) {
3071 assert(!label->IsBound()); 3076 assert(!label->isBound());
3072 intptr_t position = Buffer.size(); 3077 intptr_t position = Buffer.size();
3073 emitUint8(0); 3078 emitUint8(0);
3074 if (!getPreliminary()) 3079 if (!getPreliminary())
3075 label->NearLinkTo(position); 3080 label->nearLinkTo(position);
3076 } 3081 }
3077 3082
3078 template <class Machine> 3083 template <class Machine>
3079 void AssemblerX86Base<Machine>::emitGenericShift( 3084 void AssemblerX86Base<Machine>::emitGenericShift(
3080 int rm, Type Ty, typename Traits::GPRRegister reg, const Immediate &imm) { 3085 int rm, Type Ty, typename Traits::GPRRegister reg, const Immediate &imm) {
3081 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 3086 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
3082 assert(imm.is_int8()); 3087 assert(imm.is_int8());
3083 if (Ty == IceType_i16) 3088 if (Ty == IceType_i16)
3084 emitOperandSizeOverride(); 3089 emitOperandSizeOverride();
3085 if (imm.value() == 1) { 3090 if (imm.value() == 1) {
(...skipping 14 matching lines...) Expand all
3100 assert(shifter == Traits::Encoded_Reg_Counter); 3105 assert(shifter == Traits::Encoded_Reg_Counter);
3101 (void)shifter; 3106 (void)shifter;
3102 if (Ty == IceType_i16) 3107 if (Ty == IceType_i16)
3103 emitOperandSizeOverride(); 3108 emitOperandSizeOverride();
3104 emitUint8(isByteSizedArithType(Ty) ? 0xD2 : 0xD3); 3109 emitUint8(isByteSizedArithType(Ty) ? 0xD2 : 0xD3);
3105 emitOperand(rm, operand); 3110 emitOperand(rm, operand);
3106 } 3111 }
3107 3112
3108 } // end of namespace X86Internal 3113 } // end of namespace X86Internal
3109 } // end of namespace Ice 3114 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698