1# Copyright (c) 2021 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 14definitions: [] 15tests: 16 - file-name: "jnez" 17 isa: 18 title: Conditional compared to zero jump 19 description: > 20 Transfer execution to an instruction at offset bytes 21 from the beginning of the current instruction 22 if signed 32-bit integer in accumulator compares with 0 as specified. 23 Offset is sign extended to the size of instruction address. 24 exceptions: 25 - x_none 26 commands: 27 28 - file-name: "op" 29 isa: 30 instructions: 31 - sig: jnez imm:i32 32 acc: in:i32 33 format: [op_imm_8, op_imm_16] 34 verification: 35 - branch_target 36 description: > 37 Check jump occurs or not occurs, depending on `acc!=0` condition 38 for forward, backward, or current cases. 39 code-template: | 40 # 41 %s 42 check-type: exit-positive 43 cases: 44 - values: 45 - | 46 # Check forward jump 47 ldai 1 48 jnez label 49 ldai 255 ##*65536 50 return # should be jumped over 51 label: 52 - values: 53 - | 54 # Check backward jump 55 jmp label2 56 label1: 57 jmp label3 58 ldai 255 ##*65536 59 label2: 60 ldai 1 61 jnez label1 62 ldai 255 63 return # should be jumped over 64 label3: 65 - values: 66 - | 67 # Check jump to itself 68 ldai 0 69 loop: 70 jnez loop 71 bugid: ['3468'] 72 - values: 73 - | 74 # Check jump to itself 75 ldai 1 76 loop: 77 jnez loop 78 runner-options: [compile-only] 79 80 - file-name: "op_bounds" 81 isa: 82 instructions: 83 - sig: jnez imm:i32 84 acc: in:i32 85 format: [op_imm_8, op_imm_16] 86 description: > 87 Check jump occurs or not occurs, depending on `acc != 0` condition 88 for forward and backward cases. 89 code-template: | 90 # 91 %s 92 check-type: none 93 cases: 94 - values: 95 - | 96 # Max forward jump for imm8, 2 + 124 + 1 = 127 bytes 97 ldai 1 98 jnez label # 2-byte instruction 99 ldai 1 ##*62 100 return 101 label: 102 ldai 0 103 return 104 - values: 105 - | 106 # Max backward jump for imm8, 1 + 2 + 2*61 + 1 + 2 = 128 bytes 107 jmp label2 108 label: 109 neg 110 ldai 61 111 subi 1 ##*61 112 return 113 label2: 114 ldai 1 115 jnez label 116 return 117 - values: 118 - | 119 # Max forward jump for imm16, 3 + 32760 + 4 = 32767 bytes 120 ldai 1 121 jnez label # 3-byte instruction 122 movi.64 v0, 0 ##*3276 123 neg 124 ldai 3 125 return 126 label: 127 ldai 0 128 return 129 - values: 130 - | 131 # Max backward jump for imm16, 1 + 4 + 32760 + 1 + 2 = 32768 bytes 132 jmp label2 133 label: 134 ldai 0 135 return 136 ldai 1 137 movi.64 v0, 0 ##*3276 138 return 139 label2: 140 ldai 1 141 jnez label 142 return 143 144 - file-name: "vals" 145 isa: 146 instructions: 147 - sig: jnez imm:i32 148 acc: in:i32 149 format: [op_imm_8, op_imm_16] 150 description: > 151 Check jump not occurs if `acc >= 0` 152 for different values in acc. 153 code-template: | 154 # 155 ldai 0 156 jnez label_bad 157 ldai %s 158 jnez label_good 159 label_bad: 160 ldai 255 161 return # should be jumped over 162 label_good: 163 check-type: exit-positive 164 cases: 165 - values: 166 - "1" 167 - values: 168 - "-1" 169 - values: 170 - "0x80000000" 171 - values: 172 - "0xFFFFFFFF" 173 - values: 174 - "0x7FFFFFFF" 175 176 - file-name: "type" 177 isa: 178 instructions: 179 - sig: jnez imm:i32 180 acc: in:i32 181 format: [op_imm_8, op_imm_16] 182 verification: 183 - acc_type 184 description: > 185 Check `jnez` with invalid types in acc. 186 tags: ['verifier'] 187 runner-options: ['verifier-failure', 'verifier-debug-config'] 188 header-template: [] 189 code-template: | 190 # 191 .record A {} 192 .record panda.String <external> 193 .record panda.Object <external> 194 .function i32 main() { 195 %s 196 jnez label 197 ldai 255 198 label: 199 check-type: exit-positive 200 cases: 201 - values: 202 - lda.null 203 - values: 204 - ldai.64 0 205 - values: 206 - fldai.64 0 207 - values: 208 - lda.type A 209 - values: 210 - lda.type A[] 211 - values: 212 - lda.type panda.String 213 - values: 214 - | 215 newobj v0, A 216 lda.obj v0 217 - values: 218 - | 219 newobj v0, panda.Object 220 lda.obj v0 221 - values: 222 - lda.str "0" 223 - values: 224 - | 225 # 226 movi v0, 10 227 newarr v0, v0, i32[] 228 lda.obj v0 229 230 - file-name: "outside_function" 231 isa: 232 instructions: 233 - sig: jnez imm:i32 234 acc: in:i32 235 format: [op_imm_8, op_imm_16] 236 verification: 237 - branch_target 238 description: Check that jump outside method is not allowed. 239 runner-options: ['compile-failure'] 240 header-template: [] 241 code-template: | 242 # 243 .function i32 f() { 244 label: 245 ldai 255 246 return 247 } 248 .function i32 main() { 249 ldai 1 250 jnez label 251 check-type: exit-positive 252 253 - file-name: "outside_try_catch_p" 254 isa: 255 instructions: 256 - sig: jnez imm:i32 257 acc: in:i32 258 format: [op_imm_8, op_imm_16] 259 description: Jump outside try/catch block. 260 bugid: ['3425'] 261 header-template: [] 262 code-template: | 263 .record panda.ArithmeticException <external> 264 .function i32 main() { 265 begin: 266 ldai 1 267 jnez outside 268 newobj v0, panda.ArithmeticException 269 throw v0 270 end: 271 ldai 1 272 return 273 catch_ae: 274 ldai 2 275 return 276 .catch panda.ArithmeticException, begin, end, catch_ae 277 ldai 3 278 return 279 outside: 280 check-type: exit-positive 281 282 - file-name: uninitialized_regs 283 isa: 284 instructions: 285 - sig: jnez imm:i32 286 acc: in:i32 287 format: [op_imm_8, op_imm_16] 288 description: Check `jnez` with uninitialized acc. 289 tags: ['verifier'] 290 runner-options: ['verifier-failure', 'verifier-debug-config'] 291 code-template: | 292 # 293 label: 294 jnez label 295 check-type: exit-positive 296 297 - file-name: "invalid_branch_target" 298 isa: 299 verification: 300 - branch_target 301 runner-options: [compile-failure] 302 description: Check 'jnez' instruction with invalid branch target. 303 header-template: [] 304 code-template: | 305 .record R {} 306 307 .function void R.ctor(R a0) <ctor> { 308 lbl_ctor: 309 return.void 310 } 311 312 .function void R.cctor() <cctor> { 313 lbl_cctor: 314 return.void 315 } 316 317 .function i32 foo(i32 a0, i32 a1) <static> { 318 lda a0 319 jnez %s 320 return 321 } 322 323 .function i32 bar() <static> { 324 lbl_bar: 325 ldai 1 326 return 327 } 328 329 .function i32 main() { 330 movi v0, 0 331 movi v1, 1 332 call.short foo, v0, v1 333 lbl_main: 334 check-type: exit-positive 335 cases: 336 - values: ["main"] 337 - values: ["foo"] 338 - values: ["bar"] 339 - values: ["baz"] 340 - values: ["R"] 341 - values: ["lbl_main"] 342 - values: ["lbl_bar"] 343 - values: ["lbl_ctor"] 344 - values: ["lbl_cctor"] 345 346 347 - file-name: "prohibited_branch_target" 348 isa: 349 verification: 350 - branch_target 351 runner-options: ['verifier-failure', 'verifier-debug-config'] 352 tags: [verifier] 353 description: Check 'jnez' instruction with prohibited branch target. 354 header-template: [] 355 code-template: | 356 .record E1 {} 357 .record E2 {} 358 359 .function i32 main() { 360 ldai 1 361 jnez %s 362 363 begin: 364 ldai 0 365 return 366 mid: 367 ldai 1 368 return 369 end: 370 ldai 2 371 return 372 373 catch_E1_begin: 374 ldai 3 375 return 376 catch_E1_mid: 377 ldai 4 378 return 379 catch_E1_end: 380 ldai 5 381 return 382 383 catch_E2_begin: 384 ldai 6 385 return 386 catch_E2_mid: 387 ldai 7 388 return 389 catch_E2_end: 390 391 quit: 392 ldai 8 393 return 394 395 .catch E1, begin, end, catch_E1_begin, catch_E1_end 396 .catch E2, catch_E1_begin, catch_E1_end, catch_E2_begin, catch_E2_end 397 outside: 398 check-type: none 399 cases: 400 - values: ["begin"] 401 runner-options: ['verifier-only', 'verifier-debug-config'] 402 - values: ["mid"] 403 runner-options: ['verifier-only', 'verifier-debug-config'] 404 - values: ["end"] 405 runner-options: ['verifier-only', 'verifier-debug-config'] 406 - values: ["quit"] 407 runner-options: ['verifier-only', 'verifier-debug-config'] 408 - values: ["catch_E1_begin"] 409 - values: ["catch_E1_mid"] 410 - values: ["catch_E1_end"] 411 runner-options: ['verifier-only', 'verifier-debug-config'] 412 - values: ["catch_E2_begin"] 413 - values: ["catch_E2_mid"] 414 - values: ["catch_E2_end"] 415 runner-options: ['verifier-only', 'verifier-debug-config'] 416 - values: ["outside"] 417