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 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-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 0 207 - values: 208 - fldai.64 0 209 - values: 210 - lda.type A 211 - values: 212 - lda.type A[] 213 - values: 214 - lda.type panda.String 215 - values: 216 - | 217 newobj v0, A 218 lda.obj v0 219 - values: 220 - | 221 newobj v0, panda.Object 222 lda.obj v0 223 - values: 224 - lda.str "0" 225 - values: 226 - | 227 # 228 movi v0, 10 229 newarr v0, v0, i32[] 230 lda.obj v0 231 232 - file-name: "outside_function" 233 isa: 234 instructions: 235 - sig: jnez imm:i32 236 acc: in:i32 237 format: [op_imm_8, op_imm_16] 238 verification: 239 - branch_target 240 description: Check that jump outside method is not allowed. 241 runner-options: ['compile-failure'] 242 header-template: [] 243 code-template: | 244 # 245 .function i32 f() { 246 label: 247 ldai 255 248 return 249 } 250 .function i32 main() { 251 ldai 1 252 jnez label 253 check-type: exit-positive 254 255 - file-name: "outside_try_catch_p" 256 isa: 257 instructions: 258 - sig: jnez imm:i32 259 acc: in:i32 260 format: [op_imm_8, op_imm_16] 261 description: Jump outside try/catch block. 262 bugid: ['3425'] 263 header-template: [] 264 code-template: | 265 .record panda.ArithmeticException <external> 266 .function i32 main() { 267 begin: 268 ldai 1 269 jnez outside 270 newobj v0, panda.ArithmeticException 271 throw v0 272 end: 273 ldai 1 274 return 275 catch_ae: 276 ldai 2 277 return 278 .catch panda.ArithmeticException, begin, end, catch_ae 279 ldai 3 280 return 281 outside: 282 check-type: exit-positive 283 284 - file-name: "outside_try_catch_j" 285 isa: 286 instructions: 287 - sig: jnez imm:i32 288 acc: in:i32 289 format: [op_imm_8, op_imm_16] 290 description: Jump outside try/catch block. 291 bugid: ['3425'] 292 header-template: [] 293 runner-options: ['use-pa'] 294 code-template: | 295 .language PandaAssembly 296 .record panda.NullPointerException <external> 297 .function i32 main() { 298 begin: 299 ldai 1 300 jnez outside 301 mov.null v0 302 throw v0 303 end: 304 ldai 1 305 return 306 catch_npe: 307 ldai 2 308 return 309 .catch panda.NullPointerException, begin, end, catch_npe 310 ldai 3 311 return 312 outside: 313 check-type: exit-positive 314 315 - file-name: uninitialized_regs 316 isa: 317 instructions: 318 - sig: jnez imm:i32 319 acc: in:i32 320 format: [op_imm_8, op_imm_16] 321 description: Check `jnez` with uninitialized acc. 322 tags: ['verifier'] 323 runner-options: ['verifier-failure', 'verifier-config'] 324 code-template: | 325 # 326 label: 327 jnez label 328 check-type: exit-positive 329 330 - file-name: "invalid_branch_target" 331 isa: 332 verification: 333 - branch_target 334 runner-options: [compile-failure] 335 description: Check 'jnez' instruction with invalid branch target. 336 header-template: [] 337 code-template: | 338 .record R {} 339 340 .function void R.ctor(R a0) <ctor> { 341 lbl_ctor: 342 return.void 343 } 344 345 .function void R.cctor() <cctor> { 346 lbl_cctor: 347 return.void 348 } 349 350 .function i32 foo(i32 a0, i32 a1) <static> { 351 lda a0 352 jnez %s 353 return 354 } 355 356 .function i32 bar() <static> { 357 lbl_bar: 358 ldai 1 359 return 360 } 361 362 .function i32 main() { 363 movi v0, 0 364 movi v1, 1 365 call.short foo, v0, v1 366 lbl_main: 367 check-type: exit-positive 368 cases: 369 - values: ["main"] 370 - values: ["foo"] 371 - values: ["bar"] 372 - values: ["baz"] 373 - values: ["R"] 374 - values: ["lbl_main"] 375 - values: ["lbl_bar"] 376 - values: ["lbl_ctor"] 377 - values: ["lbl_cctor"] 378 379 380 - file-name: "prohibited_branch_target" 381 isa: 382 verification: 383 - branch_target 384 runner-options: ['verifier-failure', 'verifier-config'] 385 tags: [verifier] 386 description: Check 'jnez' instruction with prohibited branch target. 387 header-template: [] 388 code-template: | 389 .record E1 {} 390 .record E2 {} 391 392 .function i32 main() { 393 ldai 1 394 jnez %s 395 396 begin: 397 ldai 0 398 return 399 mid: 400 ldai 1 401 return 402 end: 403 ldai 2 404 return 405 406 catch_E1_begin: 407 ldai 3 408 return 409 catch_E1_mid: 410 ldai 4 411 return 412 catch_E1_end: 413 ldai 5 414 return 415 416 catch_E2_begin: 417 ldai 6 418 return 419 catch_E2_mid: 420 ldai 7 421 return 422 catch_E2_end: 423 424 quit: 425 ldai 8 426 return 427 428 .catch E1, begin, end, catch_E1_begin, catch_E1_end 429 .catch E2, catch_E1_begin, catch_E1_end, catch_E2_begin, catch_E2_end 430 outside: 431 check-type: none 432 cases: 433 - values: ["begin"] 434 runner-options: ['verifier-only', 'verifier-config'] 435 - values: ["mid"] 436 runner-options: ['verifier-only', 'verifier-config'] 437 - values: ["end"] 438 runner-options: ['verifier-only', 'verifier-config'] 439 - values: ["quit"] 440 runner-options: ['verifier-only', 'verifier-config'] 441 - values: ["catch_E1_begin"] 442 - values: ["catch_E1_mid"] 443 - values: ["catch_E1_end"] 444 runner-options: ['verifier-only', 'verifier-config'] 445 - values: ["catch_E2_begin"] 446 - values: ["catch_E2_mid"] 447 - values: ["catch_E2_end"] 448 runner-options: ['verifier-only', 'verifier-config'] 449 - values: ["outside"] 450