1# Copyright (c) 2021-2022 Huawei Device Co., Ltd. 2# Licensed under the Apache License, Version 2.0 (the "License"); 3# you may not use this file except in compliance with the License. 4# You may obtain a copy of the License at 5# 6# http://www.apache.org/licenses/LICENSE-2.0 7# 8# Unless required by applicable law or agreed to in writing, software 9# distributed under the License is distributed on an "AS IS" BASIS, 10# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11# See the License for the specific language governing permissions and 12# limitations under the License. 13 14 15class Codegen 16 attr_accessor :prologue 17 18 def reset_prologue 19 @prologue = '' 20 end 21 22 def reset 23 @runtime_info = false 24 end 25 26 def runtime_info 27 if !@runtime_info 28 @prologue += %Q(auto runtime_info = visitor->GetGraph()->GetRuntime();) 29 @runtime_info = true 30 end 31 'runtime_info' 32 end 33 34 def tmp_reg 35 36 end 37 38 ####################################################################################### 39 # Next methods are DSL tokens implementation 40 # 41 def safepoint_state 42 @prologue += %Q( 43 if (cg->GetGraph()->GetRuntime()->GetGCEntryPoint() == 0) { 44 // No GC_ENTRY - do not encode SafePoint 45 return; 46 } 47 auto runtime_info = visitor->GetGraph()->GetRuntime(); 48 auto flag_addr_offset = #{runtime_info}->GetFlagAddrOffset(); 49 auto tmp_reg = #{tmp 'u64'}; 50 auto arg_mem = vixl::aarch64::MemOperand(vixl::aarch64::sp, cg->GetStackOffset()); 51 __ Ldr(tmp_reg, arg_mem); 52 // TMP <= ExecState Address 53 auto safepoint_mem = vixl::aarch64::MemOperand(tmp_reg, flag_addr_offset); 54 // safepoint_mem - memory for read flag value 55 ) 56 "safepoint_mem" 57 end 58 59 def safepoint_constant 60 "#{runtime_info}->GetSafepointActiveValue()" 61 end 62 63 def back_safepoint_label 64 "cg->GetBackEdgeSP(inst)" 65 end 66 67 def safepoint_label 68 @prologue += %Q( 69 auto label = cg->GetLabelSS(inst);) 70 'label' 71 end 72 73 def ld(size, dst, src) 74 case size 75 when 8 76 "__ Ldrb(#{dst}, #{src});" 77 when 16 78 "__ Ldrh(#{dst}, #{src});" 79 else 80 "__ Ldr(#{dst}, #{src});" 81 end 82 end 83 84 def cmp(a, b) 85 "__ Cmp(#{a}), #{b});" 86 end 87 88 def jeq(a, b, target) 89 %Q(__ Cmp(#{a}, #{b}); 90 __ B(vixl::aarch64::Condition::eq, #{target});) 91 end 92 93 def jneq(a, b, target) 94 %Q(__ Cmp(#{a}, #{b}); 95 __ B(vixl::aarch64::Condition::ne, #{target});) 96 end 97 98 def bind(label) 99 %Q(__ Bind(#{label});) 100 end 101 102 def tmp(type) 103 "cg->EncodeReg(cg->GetTmp(), #{IR::get_ir_type(type)})" 104 end 105 106 ## 107 # This method aims to handle DSL tokens that don't have methods with same name, for example, ld_8 redirected to 108 # ld method with 8 passed as argument 109 # 110 def method_missing name, *args 111 if m = /^ld_(\d+)$/.match(name) 112 return ld(m[1], *args) 113 elsif m = /^tmp_([suf]\d+)$/.match(name) 114 return tmp(m[1]) 115 else 116 raise NoMethodError, "Unknown codegen command: #{name}" 117 end 118 end 119end 120