1 /* 2 * %CopyrightBegin% 3 * 4 * Copyright Ericsson AB 2021. All Rights Reserved. 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 * 18 * %CopyrightEnd% 19 */ 20 21 #include <string> 22 #include <vector> 23 #include <unordered_map> 24 #include <map> 25 26 extern "C" 27 { 28 #ifdef HAVE_CONFIG_H 29 # include "config.h" 30 #endif 31 32 #include "sys.h" 33 #include "erl_vm.h" 34 #include "global.h" 35 36 #include "beam_jit_common.h" 37 } 38 39 class ArgVal { 40 BeamOpArg gen_op; 41 42 public: 43 enum TYPE { 44 u = TAG_u, 45 i = TAG_i, 46 x = TAG_x, 47 y = TAG_y, 48 f = TAG_f, 49 q = TAG_q, 50 e = TAG_r, 51 l = TAG_l /* float register */ 52 }; 53 ArgVal(const BeamOpArg & arg)54 ArgVal(const BeamOpArg &arg) { 55 gen_op = arg; 56 } 57 ArgVal(enum TYPE t,BeamInstr val)58 ArgVal(enum TYPE t, BeamInstr val) { 59 gen_op.type = t; 60 gen_op.val = val; 61 } 62 ArgVal(unsigned t,BeamInstr val)63 ArgVal(unsigned t, BeamInstr val) { 64 #ifdef DEBUG 65 switch (t) { 66 case TAG_u: 67 break; 68 case TAG_i: 69 break; 70 case TAG_x: 71 break; 72 case TAG_y: 73 break; 74 case TAG_f: 75 break; 76 case TAG_q: 77 break; 78 case TAG_r: 79 break; 80 case TAG_l: 81 break; 82 default: 83 ASSERT(0); 84 } 85 #endif 86 87 gen_op.type = t; 88 gen_op.val = val; 89 } 90 getType() const91 constexpr enum TYPE getType() const { 92 return (enum TYPE)gen_op.type; 93 } 94 getValue() const95 constexpr uint64_t getValue() const { 96 return gen_op.val; 97 } 98 isMem() const99 constexpr bool isMem() const { 100 return gen_op.type == x || gen_op.type == y; 101 } 102 isLiteral() const103 constexpr bool isLiteral() const { 104 return gen_op.type == q; 105 } 106 isImmed() const107 constexpr bool isImmed() const { 108 return gen_op.type == i; 109 } 110 111 template<typename T> operator +(T val) const112 ArgVal operator+(T val) const { 113 return ArgVal(gen_op.type, val + gen_op.val); 114 } 115 116 template<typename T> operator *(T val) const117 ArgVal operator*(T val) const { 118 return ArgVal(gen_op.type, val * gen_op.val); 119 } 120 121 enum Relation { none, consecutive, reverse_consecutive }; 122 register_relation(const ArgVal & arg1,const ArgVal & arg2)123 static Relation register_relation(const ArgVal &arg1, const ArgVal &arg2) { 124 TYPE type = arg1.getType(); 125 bool same_reg_types = 126 type == arg2.getType() && (type == TYPE::x || type == TYPE::y); 127 if (!same_reg_types) { 128 return none; 129 } else if (arg1.getValue() + 1 == arg2.getValue()) { 130 return consecutive; 131 } else if (arg1.getValue() == arg2.getValue() + 1) { 132 return reverse_consecutive; 133 } else { 134 return none; 135 } 136 }; 137 }; 138