• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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