1#!/usr/bin/env ruby 2 3# Copyright (c) 2021-2022 Huawei Device Co., Ltd. 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16include_relative 'common.irt' 17 18function(:IrtocTestCfg, params: {"buf" => 'ptr', "size" => 'u64'}, mode: [:Native]) { 19 if Options.arch == :arm32 20 Intrinsic(:UNREACHABLE).Terminator.void 21 ReturnVoid().void 22 next 23 end 24 25 i0 := 0 26 r0 := 0 27 While((i := (i_phi := Phi(i0, i1).u64)), size).NE { 28 res := WhilePhi(r0, phi2).u64 29 30 offset := Mul(i, 8).u64 31 value := Load(buf, offset).u64 32 If(And(i, 1).u64, 0).EQ { 33 If(And(value, 1).u64, 0).EQ { 34 r1 := Add(res, 2).u64 35 v0 := Add(value, 2).u64 36 Store(buf, offset, v0).u64 37 } Else { 38 r2 := Add(res, 1).u64 39 v1 := Add(value, 1).u64 40 Store(buf, offset, v1).u64 41 } 42 phi1 := Phi(r1, r2).u64 43 } Else { 44 r3 := Sub(res, 1).u64 45 v2 := Sub(value, 1).u64 46 Store(buf, offset, v2).u64 47 } 48 phi2 := Phi(phi1, r3).u64 49 i1 := Add(i, 1).u64 50 } 51 Return(res).u64 52} 53 54function(:IrtocTestCfgLabels, params: {"buf" => 'ptr', "size" => 'u64'}, mode: [:Native]) { 55 if Options.arch == :arm32 56 Intrinsic(:UNREACHABLE).Terminator.void 57 ReturnVoid().void 58 next 59 end 60 i0 := 0 61 r0 := 0 62 63 Label(:Head) 64 i_phi := Phi(i0, i1).u64 65 res := Phi(r0, phi2).u64 66 i := i_phi 67 If(i, size).EQ.Unlikely { 68 Goto(:Exit) 69 } 70 71 offset := Mul(i, 8).u64 72 value := Load(buf, offset).u64 73 74 If(And(i, 1).u64, 0).NE { Goto(:Else1) } 75 If(And(value, 1).u64, 0).NE { Goto(:Else2) } 76 r1 := Add(res, 2).u64 77 v0 := Add(value, 2).u64 78 Store(buf, offset, v0).u64 79 Goto(:IfCont2) 80 Label(:Else2) 81 r2 := Add(res, 1).u64 82 v1 := Add(value, 1).u64 83 Store(buf, offset, v1).u64 84 Label(:IfCont2) 85 phi1 := Phi(r1, r2).u64 86 Goto(:IfCont1) 87 Label(:Else1) 88 r3 := Sub(res, 1).u64 89 v2 := Sub(value, 1).u64 90 Store(buf, offset, v2).u64 91 Label(:IfCont1) 92 phi2 := Phi(phi1, r3).u64 93 i1 := Add(i, 1).u64 94 Goto(:Head) 95 Label(:Exit) 96 Return(res).u64 97} 98 99function(:IrtocTestAddValues, params: {a: 'i64', b: 'i64'}, mode: [:Native]) { 100 v := Add(a, b).i64 101 Return(v).i64 102} 103 104function(:IrtocTestIncMaxValue, params: {a: 'u64', b: 'u64'}, mode: [:Native]) { 105 If(a, b).GE { 106 v1 := Add(a, 1).u64 107 } 108 Else { 109 v2 := Add(b, 1).u64 110 } 111 phi := Phi(v1, v2).u64 112 Return(phi).u64 113} 114 115function(:IrtocTestIncMaxValueLabels, params: {a: 'u64', b: 'u64'}, mode: [:Native]) { 116 If(a, b).GE { 117 Goto(:l1) 118 } Else { 119 Goto(:l2) 120 } 121Label(:l1) 122 v1 := Add(a, 1).u64 123 Goto(:l3) 124Label(:l2) 125 v2 := Add(b, 1).u64 126Label(:l3) 127 Return(Phi(v1, v2).u64).u64 128} 129 130function(:IrtocTestSeqLabels, params: {a: 'u64'}, mode: [:Native]) { 131 If(a, 10).LE { 132 ret1 := AddI(a).Imm(1).u64 133 Goto(:end) 134 } 135 If(a, 100).LE { 136 ret2 := AddI(a).Imm(2).u64 137 Goto(:end) 138 } 139 ret3 := AddI(a).Imm(3).u64 140Label(:end) 141 Return(Phi(ret1, ret2, ret3).u64).u64 142} 143 144# Return `TestCall(TestCall(n) * n)` 145function(:IrtocTestRelocations, params: {"n" => 'u32'}, mode: [:Native]) { 146 res := Call(n).Method("TestCall").u32 147 res := Mul(res, n).u32 148 res := Call(res).Method("TestCall").u32 149 Return(res).u32 150} 151 152function(:IrtocTestRelocations2, 153 params: {a0: 'word', a1: 'word', f0: 'f64', a2: 'word', a3: 'word', a4: 'word', f1: 'f64', f2: 'f64', a5: 'word', a6: 'word', f3: 'f64', a7: 'word', a8: 'word', a9: 'word', f4: 'f64'}, mode: [:Native]) { 154 fres := Call(f0).Method("IncrementFloat").f64 155 fres := Add(fres, Call(f1).Method("IncrementFloat").f64).f64 156 fres := Add(fres, Call(f2).Method("IncrementFloat").f64).f64 157 fres := Add(fres, Call(f3).Method("IncrementFloat").f64).f64 158 fres := Add(fres, Call(f4).Method("IncrementFloat").f64).f64 159 ares := Call(a0).Method("IncrementInt").word 160 ares := Add(ares, Call(a1).Method("IncrementInt").word).word 161 ares := Add(ares, Call(a2).Method("IncrementInt").word).word 162 ares := Add(ares, Call(a3).Method("IncrementInt").word).word 163 ares := Add(ares, Call(a4).Method("IncrementInt").word).word 164 ares := Add(ares, Call(a5).Method("IncrementInt").word).word 165 ares := Add(ares, Call(a6).Method("IncrementInt").word).word 166 ares := Add(ares, Call(a7).Method("IncrementInt").word).word 167 ares := Add(ares, Call(a8).Method("IncrementInt").word).word 168 ares := Add(ares, Call(a9).Method("IncrementInt").word).word 169 170 res := Add(ares, Cast(fres).SrcType("DataType::FLOAT64").word).word 171 Return(res).word 172} 173 174# Return sum of all numbers from 0 to `n` 175# Fixed issue: #6890 176# Problem: `Goto` right after `If` block with only `Goto` inside leads to wrong graph 177function(:IrtocTestLabels, params: {n: 'word'}, mode: [:Native]) { 178 res_init := 0 179 i_init := 0 180Label(:Header) 181 res := Phi(res_init, res_next).word 182 i := Phi(i_init, i_next).word 183 184 res_next := Add(res, i).word 185 i_next := AddI(i).Imm(1).word 186 If(i_next, n).GT.Unlikely.b { 187 Goto(:Tail) 188 } 189 Goto(:Header) 190Label(:Tail) 191 Return(res_next).word 192} 193 194function(:IrtocTestReturnBeforeLabel, params: {n: 'word'}, mode: [:Native]) { 195 If(n, 100).GT.b { 196 Goto(:Exit1) 197 } Else { 198 Goto(:Exit2) 199 } 200Label(:Exit1) 201 Return(1).word 202Label(:Exit2) 203 Return(2).word 204} 205