1# Copyright (c) 2021-2025 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--- 15 16chapters: 17 - name: General Design 18 text: > 19 VM is register-based with a dedicated accumulator register that serves as an implicit operand to instructions. 20 21 - name: Registers 22 text: > 23 Registers are wide enough to hold a single reference when working with objects. 24 When used for primitive types, register width is considered to be 64 bits. 25 When used for object types, registers must be considered wide enough to hold a reference to an object. 26 The scope of a register is a *function frame* (also known as *activation record*). If an instruction defines not all 64 27 bits of a register, then the undefined bits are not accessed in a verified code. 28 Register field width in instruction encoding can be 4 (16 addressable registers), 8 (256 registers) or 29 16 (65536 registers) bits. 30 31 - name: Accumulator 32 text: > 33 *Accumulator* is a special register which is used implicitly by instructions as a source and/or destination operand. 34 The main goal of using accumulator is to improve encoding density without losing much in performance. Therefore, 35 the general intuition regarding accumulator usage is to utilize accumulator as much as possible by taking it as 36 a source from a previous instruction result and passing it to the next instruction in its destination operand. 37 Moreover, when an instruction has more than one source operand, the shorter-living value must be passed 38 through accumulator. However, instruction variations that do not write into accumulator are also introduced 39 if it gives advantage. For example, arguments for the`call.range` instruction can be moved register-to-register. 40 41 - name: Calling Sequence 42 text: > 43 A new function frame is created upon the execution of call bytecode. All necessary arguments are copied from the 44 caller frame to the top of the callee frame. E.g., the last argument is placed in the register with the largest 45 index, and the first argument is placed in the register with the index that equals the size of the frame subtracted 46 by the number of arguments. The accumulator value is considered *undefined*; it is not read in the verified bytecode. 47 Upon return, the callee frame is destroyed. If a function return value is non-void, then it is passed to the caller 48 via accumulator. Otherwise, the accumulator content in the caller frame is considered *undefined*; it is not 49 read in the verified bytecode. 50 51 - name: Supported Primitive Types 52 text: | 53 VM supports operations on registers with i32 and i64 integral values. However, 8-bit and 16-bit integral values 54 can be loaded/stored into records and arrays with corresponding bytecodes. In that case, VM extends/truncates the 55 value to match storage size with i32. Similarly, passing an 8-bit or 16-bit value to a function can be emulated by 56 passing a value, which is zero or sign-extended to i32. 57 VM supports operations on registers with f32 and f64 values, which correspond to the IEEE-754 single and double precision 58 floating-point representations. 59 Primitive data type of a register is not tracked by VM and is interpreted by separate bytecodes. 60 Integral values are not inherently signed or unsigned. Their signedness is interpreted by bytecodes as well. 61 If bytecode treats a register value as a signed integer, then it uses two's complement representation. 62 If bytecode treats a register value as an unsigned integer, then the bytecode is denoted by using the u32/u64 notation. 63 It is not always possible to denote the type of result for moves, loads and stores, because it depends on the type of the 64 source object. If it is not possible to denote the type of result, then bNN notation is used, where NN is the bit size of 65 the result. Therefore, for example, b64 is a union of f64 and i64. 66 67 ### Floating-point literals 68 69 Decimal floating-point literals can have the following parts: 70 71 - Sign ('``+``' or '``-`'`), 72 - Whole number part, 73 - Decimal point, 74 - Fractional part, 75 - Exponent indicator ('``e``'), 76 - Exponent sign, 77 - Exponent. 78 79 Decimal floating-point literals must have at least one digit, plus either a decimal point or an exponent part. 80 81 Special values: 82 83 - Positive zero (+0.0, hexadecimal representation is `0x0000000000000000`), 84 - Negative zero (-0.0, hexadecimal representation is `0x8000000000000000`), 85 - Minimal positive value (4.9E-324, hexadecimal representation is `0x0000000000000001`), 86 - Maximal negative value (-4.9E-324, hexadecimal representation is `0x8000000000000001`), 87 - Maximal positive value (1.7976931348623157e308, hexadecimal representation is `0x7fefffffffffffff`), 88 - Minimal negative value (-1.7976931348623157e308, hexadecimal representation is `0xffefffffffffffff`), 89 - Positive infinity (hexadecimal representation is `0x7ff0000000000000`), 90 - Negative infinity (hexadecimal representation is `0xfff0000000000000`), 91 - Not a number - set of all NaN values (one of hexadecimal representations is `0x7ff8000000000000`). 92 93 - name: Language-Dependent Types 94 text: > 95 Panda VM supports type hierarchies according to the language it executes. Therefore, creation (or loading 96 from a constant pool) of strings, arrays, and exception objects produces objects of types native to the 97 language, including inheritance relations. 98 99 - name: Dynamically-Typed Languages Support 100 text: > 101 Panda VM supports dynamically-typed languages. It represents a dynamic value through a special 'any' value. 'Any' values 102 wrap each value itself (both primitive value and object) with its corresponding type info. VM tracks types of registers 103 that hold 'any' values, whether primitive or not. Virtual registers and accumulator are wide enough to hold an 'any' 104 value. Regular static instructions can also be used when the VM executes a code inside a dynamically-typed language context. 105 106# File format and ISA versioning 107min_version: 0.0.0.5 108version: 0.0.0.5 109 110properties: 111 - tag: type_id 112 description: Use an id which resolves into a type constant. 113 - tag: method_id 114 description: Use an id which resolves into a method constant. 115 - tag: static_method_id 116 description: Use an id which resolves into a static method constant. 117 - tag: string_id 118 description: Use an id which resolves into a string constant. 119 - tag: literalarray_id 120 description: Use an id which resolves into a constant literalarray. 121 - tag: field_id 122 description: Use an id which resolves into an instance field reference. 123 - tag: static_field_id 124 description: Use an id which resolves into a static field reference. 125 - tag: short_long_range 126 description: Instruction is used to pass arguments, exists in short, long and range forms. 127 - tag: call 128 description: Pass control to the callee method. 129 - tag: call_virt 130 description: Pass control to the callee method via virtual call. 131 - tag: return 132 description: Pass control to the caller method. 133 - tag: suspend 134 description: Suspend current method and pass control to the caller one. 135 - tag: jump 136 description: Pass control to another bytecode in a current method. 137 - tag: conditional 138 description: Operate based on computed condition, otherwise is no operation. 139 - tag: float 140 description: Perform floating point operation. 141 - tag: dynamic 142 description: Operates on 'any' values. 143 - tag: maybe_dynamic 144 description: May operate on 'any' values depending on language context. 145 - tag: language_type 146 description: Creates objects of type depending on language context. 147 - tag: initialize_type 148 description: May initialize type instance during execution. 149 - tag: init_obj 150 description: Calls the object initialization function. 151exceptions: 152 - tag: x_none 153 description: Bytecode doesn't throw exceptions. 154 - tag: x_null 155 description: Bytecode throws NullPointerException in case of null reference as a source. 156 - tag: x_bounds 157 description: Bytecode throws ArrayIndexOutOfBoundsException if index is out of bounds of an array. 158 - tag: x_negsize 159 description: Bytecode throws NegativeArraySizeException if index is less than zero. 160 - tag: x_store 161 description: Bytecode throws ArrayStoreException if element isn't instance of array's element type. 162 - tag: x_abstract 163 description: Bytecode throws AbstractMethodError if resolved method has no implementation. 164 - tag: x_arith 165 description: Bytecode throws ArithmeticException if the divisor is 0. 166 - tag: x_cast 167 description: Bytecode throws ClassCastException if type cast failed. 168 - tag: x_classdef 169 description: Bytecode throws NoClassDefFoundError if type cast failed. 170 - tag: x_oom 171 description: Bytecode throws OutOfMemoryError if failed to allocate object. 172 - tag: x_init 173 description: Bytecode throws ExceptionInInitializerError if unexpected exception occurred in a static initializer. 174 - tag: x_call 175 description: Bytecode may throw an error if an exception occurs in the called bytecode. 176 - tag: x_throw 177 description: Bytecode's primary role is to throw provided exception object. 178 - tag: x_link 179 description: Bytecode may throw NoClassDefFoundError if failed to resolve id. 180verification: 181 - tag: none 182 description: Instruction is always valid. 183 - tag: v1_array 184 description: First operand contains a reference to an array. 185 - tag: v1_object 186 description: First operand contains a reference to an object (other than array). 187 - tag: v1_array_type 188 # TODO: specify 189 description: First operand contains a reference to an array of elements of type corresponding to bytecode. 190 - tag: v1_i32 191 description: First operand contains a value of i32 type. 192 - tag: v1_type 193 description: First operand contains a value of type corresponding to bytecode. 194 - tag: v1_obj_or_null 195 description: First operand contains a reference to an object or null. 196 - tag: v2_i32 197 description: Second operand contains a value of i32 type. 198 - tag: v2_object 199 description: Second operand contains a reference to an object (other than array). 200 - tag: v2_type 201 description: Second operand contains a value of type corresponding to bytecode. 202 - tag: acc_i32 203 description: Accumulator contains a value of i32 type. 204 - tag: acc_type 205 description: Accumulator contains a value of type corresponding to bytecode. # TODO: specify 206 - tag: acc_return_type 207 # TODO: specify, including assignment compatibility (see Java 'areturn') 208 description: Accumulator type is compatible with method return type. 209 - tag: v1_throw_type 210 description: First operand contains a reference to an instance of class Throwable or of a subclass of Throwable. 211 - tag: acc_obj_or_null 212 description: Accumulator contains a reference to an object or null. 213 - tag: type_id_array 214 description: Type_id operand must correspond to an array type. 215 - tag: type_id_object 216 description: Type_id operand must correspond to an object type (other than array). 217 - tag: type_id_any_object 218 description: Type_id operand must correspond to any object type. 219 - tag: type_id_class 220 description: Type_id operand must correspond to a Class type. 221 - tag: method_id_static 222 description: Method_id must resolve to a static method or into initializer for a type other than one-dimensional array. 223 - tag: method_id_non_static 224 description: Method_id must resolve to a non-static method. 225 - tag: method_id_non_abstract 226 description: Method_id must resolve to a method that has implementation. 227 - tag: method_id_accessible 228 description: Method_id must resolve to a method which is accessible. 229 - tag: constant_string_id 230 description: Id must resolve into a constant-pool string. 231 - tag: constant_literalarray_id 232 description: Id must resolve into a constant literalarray. 233 - tag: compatible_arguments 234 description: Arguments provided to a method must be of compatible types. # TODO: specify compatibility 235 - tag: method_init_obj 236 description: Method_id must resolve into initializer for a type other than one-dimensional array. 237 - tag: branch_target 238 description: Branch target should point to a beginning of an instruction of the same method. 239 - tag: field_id_non_static 240 description: Field_id must resolve to a non-static object field. 241 - tag: field_id_static 242 description: Field_id must resolve to a static field. 243 - tag: field_id_size 244 description: Field_id must resolve to a field of size corresponding to bytecode. 245 - tag: valid_in_dynamic_context 246 description: Instruction valid only for dynamically-typed language context. 247 248prefixes: 249 - name: bit 250 description: Bit operations. 251 opcode_idx: 0xef 252 - name: unsigned 253 description: Unsigned operations. 254 opcode_idx: 0xee 255 - name: cast 256 description: Cast operations. 257 opcode_idx: 0xed 258 - name: f32 259 description: IEEE-754 single precision floating-point operations. 260 opcode_idx: 0xec 261 262# Define elements allowed to be used in a profile description. 263profiles_schema: {} 264 265# Profiles should be specified in an ISA description for a specific language. 266profiles: [] 267 268namespaces: 269 - namespace: core 270 used_instructions: [] 271 272groups: 273 - title: No operation 274 description: Perform an operation without behavior. 275 exceptions: 276 - x_none 277 verification: 278 - none 279 pseudo: | 280 skip 281 instructions: 282 - sig: nop 283 acc: none 284 format: [op_none] 285 opcode_idx: [0x0] 286 287 - title: Move register-to-register 288 description: Move values between registers. 289 exceptions: 290 - x_none 291 verification: 292 - v2_type 293 pseudo: | 294 vd = vs 295 instructions: 296 - sig: mov v1:out:b32, v2:in:b32 297 acc: none 298 format: [op_v1_4_v2_4, op_v1_8_v2_8, op_v1_16_v2_16] 299 opcode_idx: [0x1, 0x2, 0x3] 300 - sig: mov.64 v1:out:b64, v2:in:b64 301 acc: none 302 format: [op_v1_4_v2_4, op_v1_16_v2_16] 303 opcode_idx: [0x4, 0x5] 304 - sig: mov.obj v1:out:ref, v2:in:ref 305 acc: none 306 format: [op_v1_4_v2_4, op_v1_8_v2_8, op_v1_16_v2_16] 307 opcode_idx: [0x6, 0x7, 0x8] 308 309 - title: Move immediate-to-register 310 description: > 311 Move integer immediate into a register. For short formats immediate is sign-extended to operand size. 312 exceptions: 313 - x_none 314 verification: 315 - none 316 pseudo: > 317 vd = imm 318 instructions: 319 - sig: movi v:out:i32, imm:i32 320 acc: none 321 format: [op_v_4_imm_4, op_v_8_imm_8, op_v_8_imm_16, op_v_8_imm_32] 322 opcode_idx: [0x9, 0xa, 0xb, 0xc] 323 - sig: movi.64 v:out:i64, imm:i64 324 acc: none 325 format: [op_v_8_imm_64] 326 opcode_idx: [0xd] 327 - sig: fmovi v:out:f32, imm:f32 328 acc: none 329 prefix: f32 330 format: [pref_op_v_8_imm_32] 331 opcode_idx: [0x0] 332 properties: [float] 333 - sig: fmovi.64 v:out:f64, imm:f64 334 acc: none 335 format: [op_v_8_imm_64] 336 opcode_idx: [0xe] 337 properties: [float] 338 339 - title: Move null reference into the register 340 description: Move null reference into the register. 341 exceptions: 342 - x_none 343 verification: 344 - none 345 pseudo: > 346 vd = null 347 instructions: 348 - sig: mov.null v:out:ref 349 acc: none 350 format: [op_v_8] 351 opcode_idx: [0xf] 352 353 - title: Load accumulator from the register 354 description: Moves register content into accumulator. 355 exceptions: 356 - x_none 357 verification: 358 - v1_type 359 pseudo: | 360 acc = vs 361 instructions: 362 - sig: lda v:in:b32 363 acc: out:b32 364 format: [op_v_8] 365 opcode_idx: [0x10] 366 - sig: lda.64 v:in:b64 367 acc: out:b64 368 format: [op_v_8] 369 opcode_idx: [0x11] 370 - sig: lda.obj v:in:ref 371 acc: out:ref 372 format: [op_v_8] 373 opcode_idx: [0x12] 374 375 - title: Load accumulator from immediate 376 description: > 377 Load immediate into accumulator. For short formats immediate is sign-extended to operand size. 378 exceptions: 379 - x_none 380 verification: 381 - none 382 pseudo: | 383 acc = imm 384 instructions: 385 - sig: ldai imm:i32 386 acc: out:i32 387 format: [op_imm_8, op_imm_16, op_imm_32] 388 opcode_idx: [0x13, 0x14, 0x15] 389 - sig: ldai.64 imm:i64 390 acc: out:i64 391 format: [op_imm_64] 392 opcode_idx: [0x16] 393 - sig: fldai imm:f32 394 acc: out:f32 395 prefix: f32 396 format: [pref_op_imm_32] 397 opcode_idx: [0x1] 398 properties: [float] 399 - sig: fldai.64 imm:f64 400 acc: out:f64 401 format: [op_imm_64] 402 opcode_idx: [0x17] 403 properties: [float] 404 405 - title: Load accumulator from string constant pool 406 description: > 407 Load string specified by id into accumulator. In dynamically-typed language context 408 load string as 'any' value. 409 properties: 410 - string_id 411 - language_type 412 - maybe_dynamic 413 exceptions: 414 - x_oom 415 verification: 416 - constant_string_id 417 pseudo: | 418 acc = load(id) 419 instructions: 420 - sig: lda.str string_id 421 acc: out:ref 422 format: [op_id_32] 423 opcode_idx: [0x18] 424 425 - title: Create and initialize new constant array 426 description: > 427 Create a new single-dimensional constant literal array and put a reference to it into register. 428 properties: 429 - literalarray_id 430 exceptions: 431 - x_oom 432 verification: 433 - constant_literalarray_id 434 pseudo: | 435 arr = load(id) 436 if arr == nullptr then 437 throw OutOfMemoryError 438 end 439 v = arr 440 instructions: 441 - sig: lda.const v:out:ref, literalarray_id 442 acc: none 443 format: [op_v_8_id_16] 444 opcode_idx: [0x19] 445 446 - title: Load accumulator from type constant pool 447 description: Load type specified by id into accumulator. 448 properties: 449 - type_id 450 - language_type 451 exceptions: 452 - x_link 453 verification: 454 - type_id_class 455 pseudo: | 456 type = load(id) 457 if type == nullptr then 458 throw NoClassDefFoundError 459 end 460 acc = type 461 instructions: 462 - sig: lda.type type_id 463 acc: out:ref 464 format: [op_id_16] 465 opcode_idx: [0x1a] 466 467 - title: Load null reference into accumulator 468 description: Load null reference into accumulator. 469 exceptions: 470 - x_none 471 verification: 472 - none 473 pseudo: | 474 acc = null 475 instructions: 476 - sig: lda.null 477 acc: out:ref 478 format: [op_none] 479 opcode_idx: [0x1b] 480 481 - title: Store accumulator 482 description: Moves accumulator content into a register. 483 exceptions: 484 - x_none 485 verification: 486 - acc_type 487 pseudo: | 488 vd = acc 489 instructions: 490 - sig: sta v:out:b32 491 acc: in:b32 492 format: [op_v_8] 493 opcode_idx: [0x1c] 494 - sig: sta.64 v:out:b64 495 acc: in:b64 496 format: [op_v_8] 497 opcode_idx: [0x1d] 498 - sig: sta.obj v:out:ref 499 acc: in:ref 500 format: [op_v_8] 501 opcode_idx: [0x1e] 502 503 - title: Integer comparison 504 description: Perform specified signed or unsigned integer comparison between register and accumulator. 505 exceptions: 506 - x_none 507 verification: 508 - acc_type 509 - v1_type 510 pseudo: | 511 if acc < vs then 512 acc = -1 513 else if acc == vs then 514 acc = 0 515 else 516 acc = 1 517 end 518 instructions: 519 - sig: cmp.64 v:in:i64 520 acc: inout:i64->i32 521 format: [op_v_8] 522 opcode_idx: [0x1f] 523 - sig: ucmp v:in:u32 524 acc: inout:u32->i32 525 prefix: unsigned 526 format: [pref_op_v_8] 527 opcode_idx: [0x0] 528 - sig: ucmp.64 v:in:u64 529 acc: inout:u64->i32 530 prefix: unsigned 531 format: [pref_op_v_8] 532 opcode_idx: [0x1] 533 534 - title: Floating-point comparison 535 description: Perform specified floating-point comparison between register and accumulator. 536 properties: 537 - float 538 exceptions: 539 - x_none 540 verification: 541 - acc_type 542 - v1_type 543 pseudo: | 544 if isnan(acc) or isnan(vs) then 545 switch (op) 546 case fcmpg: 547 case fcmpg.64: 548 acc = 1 549 case fcmpl: 550 case fcmpl.64: 551 acc = -1 552 else 553 if acc < vs then 554 acc = -1 555 else if acc == vs then 556 acc = 0 557 else 558 acc = 1 559 end 560 end 561 instructions: 562 - sig: fcmpl v:in:f32 563 acc: inout:f32->i32 564 prefix: f32 565 format: [pref_op_v_8] 566 opcode_idx: [0x2] 567 - sig: fcmpl.64 v:in:f64 568 acc: inout:f64->i32 569 format: [op_v_8] 570 opcode_idx: [0x20] 571 - sig: fcmpg v:in:f32 572 acc: inout:f32->i32 573 prefix: f32 574 format: [pref_op_v_8] 575 opcode_idx: [0x3] 576 - sig: fcmpg.64 v:in:f64 577 acc: inout:f64->i32 578 format: [op_v_8] 579 opcode_idx: [0x21] 580 581 - title: Unconditional jump 582 description: > 583 Unconditionally transfer execution to an instruction at offset bytes from the beginning of the current 584 instruction. Offset is sign-extended to the size of instruction address. 585 properties: 586 - jump 587 exceptions: 588 - x_none 589 verification: 590 - branch_target 591 pseudo: | 592 pc += imm 593 instructions: 594 - sig: jmp imm:i32 595 acc: none 596 format: [op_imm_8, op_imm_16, op_imm_32] 597 opcode_idx: [0x22, 0x23, 0x24] 598 599 - title: Conditional object comparison jump 600 description: > 601 Transfer execution to an instruction at offset bytes from the beginning of the current instruction if 602 object references in accumulator and source register compare as specified. Offset is sign-extended to the size of 603 instruction address. 604 properties: 605 - jump 606 - conditional 607 exceptions: 608 - x_none 609 verification: 610 - branch_target 611 - acc_obj_or_null 612 - v1_obj_or_null 613 pseudo: | 614 switch (cc) 615 case eq: 616 if acc == vs then 617 pc += imm 618 end 619 case ne: 620 if acc != vs then 621 pc += imm 622 end 623 instructions: 624 - sig: jeq.obj v:in:ref, imm:i32 625 acc: in:ref 626 format: [op_v_8_imm_8, op_v_8_imm_16] 627 opcode_idx: [0x25, 0x26] 628 - sig: jne.obj v:in:ref, imm:i32 629 acc: in:ref 630 format: [op_v_8_imm_8, op_v_8_imm_16] 631 opcode_idx: [0x27, 0x28] 632 633 - title: Conditional compared to null jump 634 description: > 635 Transfer execution to an instruction at offset bytes from the beginning of the current instruction if 636 object reference in accumulator compares with null as specified. Offset is sign-extended to the size of 637 instruction address. 638 properties: 639 - jump 640 - conditional 641 exceptions: 642 - x_none 643 verification: 644 - branch_target 645 - acc_obj_or_null 646 pseudo: | 647 switch (cc) 648 case eq: 649 if acc == null then 650 pc += imm 651 end 652 case ne: 653 if acc != null then 654 pc += imm 655 end 656 instructions: 657 - sig: jeqz.obj imm:i32 658 acc: in:ref 659 format: [op_imm_8, op_imm_16] 660 opcode_idx: [0x29, 0x2a] 661 - sig: jnez.obj imm:i32 662 acc: in:ref 663 format: [op_imm_8, op_imm_16] 664 opcode_idx: [0x2b, 0x2c] 665 666 - title: Conditional compared to zero jump 667 description: > 668 Transfer execution to an instruction at offset bytes from the beginning of the current instruction if 669 signed 32-bit integer in accumulator compares with 0 as specified. Offset is sign-extended to the size 670 of instruction address. 671 properties: 672 - jump 673 - conditional 674 exceptions: 675 - x_none 676 verification: 677 - branch_target 678 - acc_type 679 pseudo: | 680 switch (cc) 681 case eq: 682 if acc == 0 then 683 pc += imm 684 end 685 case ne: 686 if acc != 0 then 687 pc += imm 688 end 689 case lt: 690 if acc < 0 then 691 pc += imm 692 end 693 case gt: 694 if acc > 0 then 695 pc += imm 696 end 697 case le: 698 if acc <= 0 then 699 pc += imm 700 end 701 case ge: 702 if acc >= 0 then 703 pc += imm 704 end 705 instructions: 706 - sig: jeqz imm:i32 707 acc: in:i32 708 format: [op_imm_8, op_imm_16] 709 opcode_idx: [0x2d, 0x2e] 710 - sig: jnez imm:i32 711 acc: in:i32 712 format: [op_imm_8, op_imm_16] 713 opcode_idx: [0x2f, 0x30] 714 - sig: jltz imm:i32 715 acc: in:i32 716 format: [op_imm_8, op_imm_16] 717 opcode_idx: [0x31, 0x32] 718 - sig: jgtz imm:i32 719 acc: in:i32 720 format: [op_imm_8, op_imm_16] 721 opcode_idx: [0x33, 0x34] 722 - sig: jlez imm:i32 723 acc: in:i32 724 format: [op_imm_8, op_imm_16] 725 opcode_idx: [0x35, 0x36] 726 - sig: jgez imm:i32 727 acc: in:i32 728 format: [op_imm_8, op_imm_16] 729 opcode_idx: [0x37, 0x38] 730 731 - title: Conditional compared to register jump 732 description: > 733 Transfer execution to an instruction at offset bytes from the beginning of the current instruction if signed 734 32-bit integers in accumulator and register compare as specified. Offset is sign-extended to the size of 735 instruction address. 736 properties: 737 - jump 738 - conditional 739 exceptions: 740 - x_none 741 verification: 742 - branch_target 743 - acc_type 744 - v1_type 745 pseudo: | 746 diff = signed_cmp(acc, vs) 747 switch (cc) 748 case eq: 749 if diff == 0 then 750 pc += imm 751 end 752 case ne: 753 if diff != 0 then 754 pc += imm 755 end 756 case lt: 757 if diff < 0 then 758 pc += imm 759 end 760 case gt: 761 if diff > 0 then 762 pc += imm 763 end 764 case le: 765 if diff <= 0 then 766 pc += imm 767 end 768 case ge: 769 if diff >= 0 then 770 pc += imm 771 end 772 instructions: 773 - sig: jeq v:in:i32, imm:i32 774 acc: in:i32 775 format: [op_v_8_imm_8, op_v_8_imm_16] 776 opcode_idx: [0x39, 0x3a] 777 - sig: jne v:in:i32, imm:i32 778 acc: in:i32 779 format: [op_v_8_imm_8, op_v_8_imm_16] 780 opcode_idx: [0x3b, 0x3c] 781 - sig: jlt v:in:i32, imm:i32 782 acc: in:i32 783 format: [op_v_8_imm_8, op_v_8_imm_16] 784 opcode_idx: [0x3d, 0x3e] 785 - sig: jgt v:in:i32, imm:i32 786 acc: in:i32 787 format: [op_v_8_imm_8, op_v_8_imm_16] 788 opcode_idx: [0x3f, 0x40] 789 - sig: jle v:in:i32, imm:i32 790 acc: in:i32 791 format: [op_v_8_imm_8, op_v_8_imm_16] 792 opcode_idx: [0x41, 0x42] 793 - sig: jge v:in:i32, imm:i32 794 acc: in:i32 795 format: [op_v_8_imm_8, op_v_8_imm_16] 796 opcode_idx: [0x43, 0x44] 797 798 - title: Floating-point unary 799 description: Perform specified floating-point operation on accumulator. 800 properties: 801 - float 802 exceptions: 803 - x_none 804 verification: 805 - acc_type 806 pseudo: | 807 switch (op) 808 case fneg: 809 case fneg.64: 810 acc = -acc 811 instructions: 812 - sig: fneg 813 acc: inout:f32 814 prefix: f32 815 format: [pref_op_none] 816 opcode_idx: [0x4] 817 - sig: fneg.64 818 acc: inout:f64 819 format: [op_none] 820 opcode_idx: [0x45] 821 822 - title: Unary 823 description: Perform specified operation on accumulator. 824 exceptions: 825 - x_none 826 verification: 827 - acc_type 828 pseudo: | 829 switch (op) 830 case neg: 831 case neg.64: 832 acc = -acc 833 case not: 834 case not.64: 835 acc = ~acc 836 instructions: 837 - sig: neg 838 acc: inout:i32 839 format: [op_none] 840 opcode_idx: [0x46] 841 - sig: neg.64 842 acc: inout:i64 843 format: [op_none] 844 opcode_idx: [0x47] 845 - sig: not 846 acc: inout:i32 847 prefix: bit 848 format: [pref_op_none] 849 opcode_idx: [0x0] 850 - sig: not.64 851 acc: inout:i64 852 prefix: bit 853 format: [pref_op_none] 854 opcode_idx: [0x1] 855 856 - title: Two address binary operation on accumulator 857 description: Perform specified binary operation on accumulator and register, and store the result into accumulator. 858 exceptions: 859 - x_none 860 verification: 861 - acc_type 862 - v1_type 863 pseudo: | 864 switch (op) 865 case add2: 866 acc = (acc + vs) % 2^32 867 case add2.64: 868 acc = (acc + vs) % 2^64 869 case sub2: 870 acc = (acc - vs) % 2^32 871 case sub2.64: 872 acc = (acc - vs) % 2^64 873 case mul2: 874 acc = (acc * vs) % 2^32 875 case mul2.64: 876 acc = (acc * vs) % 2^64 877 case and2: 878 acc = acc & vs 879 case and2.64: 880 acc = acc & vs 881 case or2: 882 acc = acc | vs 883 case or2.64: 884 acc = acc | vs 885 case xor2: 886 acc = acc ^ vs 887 case xor2.64: 888 acc = acc ^ vs 889 case shl2: 890 acc = (acc << (vs & 0x1f)) % 2^32 891 case shl2.64: 892 acc = (acc << (vs & 0x3f)) % 2^64 893 case shr2: 894 acc = acc >> (vs & 0x1f) 895 case shr2.64: 896 acc = acc >> (vs & 0x3f) 897 case ashr2: 898 acc = (acc < 0) ? ~(~acc >> vs & 0x1f) : acc >> vs & 0x1f 899 case ashr2.64: 900 acc = (acc < 0) ? ~(~acc >> vs & 0x3f) : acc >> vs & 0x3f 901 instructions: 902 - sig: add2 v:in:i32 903 acc: inout:i32 904 format: [op_v_8] 905 opcode_idx: [0x48] 906 - sig: add2.64 v:in:i64 907 acc: inout:i64 908 format: [op_v_8] 909 opcode_idx: [0x49] 910 - sig: sub2 v:in:i32 911 acc: inout:i32 912 format: [op_v_8] 913 opcode_idx: [0x4a] 914 - sig: sub2.64 v:in:i64 915 acc: inout:i64 916 format: [op_v_8] 917 opcode_idx: [0x4b] 918 - sig: mul2 v:in:i32 919 acc: inout:i32 920 format: [op_v_8] 921 opcode_idx: [0x4c] 922 - sig: mul2.64 v:in:i64 923 acc: inout:i64 924 format: [op_v_8] 925 opcode_idx: [0x4d] 926 - sig: and2 v:in:i32 927 acc: inout:i32 928 prefix: bit 929 format: [pref_op_v_8] 930 opcode_idx: [0x2] 931 - sig: and2.64 v:in:i64 932 acc: inout:i64 933 prefix: bit 934 format: [pref_op_v_8] 935 opcode_idx: [0x3] 936 - sig: or2 v:in:i32 937 acc: inout:i32 938 prefix: bit 939 format: [pref_op_v_8] 940 opcode_idx: [0x4] 941 - sig: or2.64 v:in:i64 942 acc: inout:i64 943 prefix: bit 944 format: [pref_op_v_8] 945 opcode_idx: [0x5] 946 - sig: xor2 v:in:i32 947 acc: inout:i32 948 prefix: bit 949 format: [pref_op_v_8] 950 opcode_idx: [0x6] 951 - sig: xor2.64 v:in:i64 952 acc: inout:i64 953 prefix: bit 954 format: [pref_op_v_8] 955 opcode_idx: [0x7] 956 - sig: shl2 v:in:i32 957 acc: inout:i32 958 prefix: bit 959 format: [pref_op_v_8] 960 opcode_idx: [0x8] 961 - sig: shl2.64 v:in:i64 962 acc: inout:i64 963 prefix: bit 964 format: [pref_op_v_8] 965 opcode_idx: [0x9] 966 - sig: shr2 v:in:i32 967 acc: inout:i32 968 prefix: bit 969 format: [pref_op_v_8] 970 opcode_idx: [0xa] 971 - sig: shr2.64 v:in:i64 972 acc: inout:i64 973 prefix: bit 974 format: [pref_op_v_8] 975 opcode_idx: [0xb] 976 - sig: ashr2 v:in:i32 977 acc: inout:i32 978 prefix: bit 979 format: [pref_op_v_8] 980 opcode_idx: [0xc] 981 - sig: ashr2.64 v:in:i64 982 acc: inout:i64 983 prefix: bit 984 format: [pref_op_v_8] 985 opcode_idx: [0xd] 986 987 - title: Two address binary operations on accumulator with results in the register 988 description: Perform specified binary operation on accumulator and register, and store the result into the register. 989 exceptions: 990 - x_none 991 verification: 992 - acc_type 993 - v1_type 994 pseudo: | 995 switch (op) 996 case add2: 997 vd = (acc + vs) % 2^32 998 case add2.64: 999 vd = (acc + vs) % 2^64 1000 case sub2: 1001 vd = (acc - vs) % 2^32 1002 case sub2.64: 1003 vd = (acc - vs) % 2^64 1004 case mul2: 1005 vd = (acc * vs) % 2^32 1006 case mul2.64: 1007 acc = (acc * vs) % 2^64 1008 case and2: 1009 vd = acc & vs 1010 case and2.64: 1011 vd = acc & vs 1012 case or2: 1013 vd = acc | vs 1014 case or2.64: 1015 vd = acc | vs 1016 case xor2: 1017 vd = acc ^ vs 1018 case xor2.64: 1019 vd = acc ^ vs 1020 case shl2: 1021 vd = (acc << (vs & 0x1f)) % 2^32 1022 case shl2.64: 1023 vd = (acc << (vs & 0x3f)) % 2^64 1024 case shr2: 1025 vd = acc >> (vs & 0x1f) 1026 case shr2.64: 1027 vd = acc >> (vs & 0x3f) 1028 case ashr2: 1029 vd = (acc < 0) ? ~(~acc >> vs & 0x1f) : acc >> vs & 0x1f 1030 case ashr2.64: 1031 vd = (acc < 0) ? ~(~acc >> vs & 0x3f) : acc >> vs & 0x3f 1032 instructions: 1033 - sig: add2v v1:out:i32, v2:in:i32 1034 acc: in:i32 1035 format: [op_v1_8_v2_8] 1036 - sig: add2v.64 v1:out:i64, v2:in:i64 1037 acc: in:i64 1038 format: [op_v1_8_v2_8] 1039 - sig: sub2v v1:out:i32, v2:in:i32 1040 acc: in:i32 1041 format: [op_v1_8_v2_8] 1042 - sig: sub2v.64 v1:out:i64, v2:in:i64 1043 acc: in:i64 1044 format: [op_v1_8_v2_8] 1045 - sig: mul2v v1:out:i32, v2:in:i32 1046 acc: in:i32 1047 format: [op_v1_8_v2_8] 1048 - sig: mul2v.64 v1:out:i64, v2:in:i64 1049 acc: in:i64 1050 format: [op_v1_8_v2_8] 1051 - sig: and2v v1:out:i32, v2:in:i32 1052 acc: in:i32 1053 prefix: bit 1054 format: [pref_op_v1_8_v2_8] 1055 - sig: and2v.64 v1:out:i64, v2:in:i64 1056 acc: in:i64 1057 prefix: bit 1058 format: [pref_op_v1_8_v2_8] 1059 - sig: or2v v1:out:i32, v2:in:i32 1060 acc: in:i32 1061 prefix: bit 1062 format: [pref_op_v1_8_v2_8] 1063 - sig: or2v.64 v1:out:i64, v2:in:i64 1064 acc: in:i64 1065 prefix: bit 1066 format: [pref_op_v1_8_v2_8] 1067 - sig: xor2v v1:out:i32, v2:in:i32 1068 acc: in:i32 1069 prefix: bit 1070 format: [pref_op_v1_8_v2_8] 1071 - sig: xor2v.64 v1:out:i64, v2:in:i64 1072 acc: in:i64 1073 prefix: bit 1074 format: [pref_op_v1_8_v2_8] 1075 - sig: shl2v v1:out:i32, v2:in:i32 1076 acc: in:i32 1077 prefix: bit 1078 format: [pref_op_v1_8_v2_8] 1079 - sig: shl2v.64 v1:out:i64, v2:in:i64 1080 acc: in:i64 1081 prefix: bit 1082 format: [pref_op_v1_8_v2_8] 1083 - sig: shr2v v1:out:i32, v2:in:i32 1084 acc: in:i32 1085 prefix: bit 1086 format: [pref_op_v1_8_v2_8] 1087 - sig: shr2v.64 v1:out:i64, v2:in:i64 1088 acc: in:i64 1089 prefix: bit 1090 format: [pref_op_v1_8_v2_8] 1091 - sig: ashr2v v1:out:i32, v2:in:i32 1092 acc: in:i32 1093 prefix: bit 1094 format: [pref_op_v1_8_v2_8] 1095 - sig: ashr2v.64 v1:out:i64, v2:in:i64 1096 acc: in:i64 1097 prefix: bit 1098 format: [pref_op_v1_8_v2_8] 1099 1100 - title: Two address floating-point binary operation on accumulator 1101 description: | 1102 Perform specified floating-point binary operation on accumulator and register, and store the result into accumulator. 1103 The results of instructions correspond to the IEEE-754 arithmetic rules. 1104 1105 - Any operation with NaN results in the NaN value. 1106 - The sum of opposite infinities or the difference of the same-sign infinities is NaN. 1107 - Division is NaN if Infinity is divided by Infinity. 1108 - Division is NaN if zero is divided by zero. 1109 - Multiplication is NaN if zero is multiplied by infinity. 1110 - The sign of division or multiplication result is positive if both values have the same sign, or negative if the values have different signs. 1111 - Division is infinity if any nonzero value is divided by zero. 1112 - Multiplication is infinity if any nonzero value is multiplied by infinity. 1113 - The sum of two infinities of the same sign or the difference of two infinities of opposite signs is infinity. The sign of the result matches 1114 the sign of the accumulator value. 1115 - The sum or the difference of infinity and any finite value is infinity. The sign of the result matches the sign of infinity. 1116 - The sum or the difference of zeros is zero. Exceptions are the sum of two negative zeros and the difference of negative and positive zeros - the result is negative zero. 1117 1118 properties: 1119 - float 1120 exceptions: 1121 - x_none 1122 verification: 1123 - acc_type 1124 - v1_type 1125 pseudo: | 1126 switch (op) 1127 case fadd2: 1128 case fadd2.64: 1129 acc = acc + vs 1130 case fsub2: 1131 case fsub2.64: 1132 acc = acc - vs 1133 case fmul2: 1134 case fmul2.64: 1135 acc = acc * vs 1136 case fdiv2: 1137 case fdiv2.64: 1138 acc = acc / vs 1139 case fmod2: 1140 case fmod2.64: 1141 acc = acc % vs 1142 instructions: 1143 - sig: fadd2 v:in:f32 1144 acc: inout:f32 1145 prefix: f32 1146 format: [pref_op_v_8] 1147 opcode_idx: [0x5] 1148 - sig: fadd2.64 v:in:f64 1149 acc: inout:f64 1150 format: [op_v_8] 1151 opcode_idx: [0x4e] 1152 - sig: fsub2 v:in:f32 1153 acc: inout:f32 1154 prefix: f32 1155 format: [pref_op_v_8] 1156 opcode_idx: [0x6] 1157 - sig: fsub2.64 v:in:f64 1158 acc: inout:f64 1159 format: [op_v_8] 1160 opcode_idx: [0x4f] 1161 - sig: fmul2 v:in:f32 1162 acc: inout:f32 1163 prefix: f32 1164 format: [pref_op_v_8] 1165 opcode_idx: [0x7] 1166 - sig: fmul2.64 v:in:f64 1167 acc: inout:f64 1168 format: [op_v_8] 1169 opcode_idx: [0x50] 1170 - sig: fdiv2 v:in:f32 1171 acc: inout:f32 1172 prefix: f32 1173 format: [pref_op_v_8] 1174 opcode_idx: [0x8] 1175 - sig: fdiv2.64 v:in:f64 1176 acc: inout:f64 1177 format: [op_v_8] 1178 opcode_idx: [0x51] 1179 - sig: fmod2 v:in:f32 1180 acc: inout:f32 1181 prefix: f32 1182 format: [pref_op_v_8] 1183 opcode_idx: [0x9] 1184 - sig: fmod2.64 v:in:f64 1185 acc: inout:f64 1186 format: [op_v_8] 1187 opcode_idx: [0x52] 1188 1189 - title: Two address floating-point binary operations on accumulator with the results in the register. 1190 description: | 1191 Perform specified floating-point binary operation on accumulator and register, and store the result into the register. 1192 The results of instructions correspond to the IEEE-754 arithmetic rules. 1193 1194 - Any operation with NaN results in NaN value. 1195 - The sum of opposite infinities or the difference of the same-sign infinities is NaN. 1196 - Division is NaN if Infinity is divided by Infinity. 1197 - Division is NaN if zero is divided by zero. 1198 - Multiplication is NaN if zero is multiplied by infinity. 1199 - The sign of division or multiplication result is positive if both values have the same sign, negative if the values have different sign. 1200 - Division is infinity if any nonzero value is divided by zero. 1201 - Multiplication is infinity if any nonzero value is multiplied by infinity. 1202 - The sum of two infinities of the same sign or the difference of two infinities of opposite sign is infinity. 1203 The sign of result matches the sign of the accumulator value. 1204 - The sum or the difference of infinity and any finite value is infinity. The sign of result matches the sign of infinity. 1205 - The sum or the difference of zeros is zero. Exceptions are the sum of two negative zeros and the difference of negative and positive zeros - the result is negative zero. 1206 1207 properties: 1208 - float 1209 exceptions: 1210 - x_none 1211 verification: 1212 - acc_type 1213 - v1_type 1214 pseudo: | 1215 switch (op) 1216 case fadd2: 1217 case fadd2.64: 1218 vd = acc + vs 1219 case fsub2: 1220 case fsub2.64: 1221 vd = acc - vs 1222 case fmul2: 1223 case fmul2.64: 1224 vd = acc * vs 1225 case fdiv2: 1226 case fdiv2.64: 1227 vd = acc / vs 1228 case fmod2: 1229 case fmod2.64: 1230 vd = acc % vs 1231 instructions: 1232 - sig: fadd2v v1:out:f32, v2:in:f32 1233 acc: in:f32 1234 prefix: f32 1235 format: [pref_op_v1_8_v2_8] 1236 - sig: fadd2v.64 v1:out:f64, v2:in:f64 1237 acc: in:f64 1238 format: [op_v1_8_v2_8] 1239 - sig: fsub2v v1:out:f32, v2:in:f32 1240 acc: in:f32 1241 prefix: f32 1242 format: [pref_op_v1_8_v2_8] 1243 - sig: fsub2v.64 v1:out:f64, v2:in:f64 1244 acc: in:f64 1245 format: [op_v1_8_v2_8] 1246 - sig: fmul2v v1:out:f32, v2:in:f32 1247 acc: in:f32 1248 prefix: f32 1249 format: [pref_op_v1_8_v2_8] 1250 - sig: fmul2v.64 v1:out:f64, v2:in:f64 1251 acc: in:f64 1252 format: [op_v1_8_v2_8] 1253 - sig: fdiv2v v1:out:f32, v2:in:f32 1254 acc: in:f32 1255 prefix: f32 1256 format: [pref_op_v1_8_v2_8] 1257 - sig: fdiv2v.64 v1:out:f64, v2:in:f64 1258 acc: in:f64 1259 format: [op_v1_8_v2_8] 1260 - sig: fmod2v v1:out:f32, v2:in:f32 1261 acc: in:f32 1262 prefix: f32 1263 format: [pref_op_v1_8_v2_8] 1264 - sig: fmod2v.64 v1:out:f64, v2:in:f64 1265 acc: in:f64 1266 format: [op_v1_8_v2_8] 1267 1268 - title: Two address integer division and modulo on accumulator 1269 description: Perform integer division or modulo on accumulator and register, and store the result into accumulator. 1270 exceptions: 1271 - x_arith 1272 verification: 1273 - acc_type 1274 - v1_type 1275 pseudo: | 1276 if vs == 0 then 1277 throw ArithmeticException 1278 end 1279 switch (op) 1280 case div: 1281 if acc == INT32_MIN and vs == -1 then 1282 acc = INT32_MIN 1283 else 1284 acc = acc / vs 1285 end 1286 case div.64: 1287 if acc == INT64_MIN and vs == -1 then 1288 acc = INT64_MIN 1289 else 1290 acc = acc / vs 1291 end 1292 case divu: 1293 case divu.64: 1294 acc = acc / vs 1295 case mod: 1296 if acc == INT32_MIN and vs == -1 then 1297 acc = 0 1298 else 1299 acc = acc % vs 1300 end 1301 case mod.64: 1302 if acc == INT64_MIN and vs == -1 then 1303 acc = 0 1304 else 1305 acc = acc % vs 1306 end 1307 case modu: 1308 case modu.64: 1309 acc = acc % vs 1310 instructions: 1311 - sig: div2 v:in:i32 1312 acc: inout:i32 1313 format: [op_v_8] 1314 opcode_idx: [0x53] 1315 - sig: div2.64 v:in:i64 1316 acc: inout:i64 1317 format: [op_v_8] 1318 opcode_idx: [0x54] 1319 - sig: mod2 v:in:i32 1320 acc: inout:i32 1321 format: [op_v_8] 1322 opcode_idx: [0x55] 1323 - sig: mod2.64 v:in:i64 1324 acc: inout:i64 1325 format: [op_v_8] 1326 opcode_idx: [0x56] 1327 - sig: divu2 v:in:u32 1328 acc: inout:u32 1329 prefix: unsigned 1330 format: [pref_op_v_8] 1331 opcode_idx: [0x2] 1332 - sig: divu2.64 v:in:u64 1333 acc: inout:u64 1334 prefix: unsigned 1335 format: [pref_op_v_8] 1336 opcode_idx: [0x3] 1337 - sig: modu2 v:in:u32 1338 acc: inout:u32 1339 prefix: unsigned 1340 format: [pref_op_v_8] 1341 opcode_idx: [0x4] 1342 - sig: modu2.64 v:in:u64 1343 acc: inout:u64 1344 prefix: unsigned 1345 format: [pref_op_v_8] 1346 opcode_idx: [0x5] 1347 1348 - title: Two address integer division and modulo on accumulator with the result in the register 1349 description: Perform integer division or modulo on accumulator and register, and store the result into the register. 1350 exceptions: 1351 - x_arith 1352 verification: 1353 - acc_type 1354 - v1_type 1355 pseudo: | 1356 if vs == 0 then 1357 throw ArithmeticException 1358 end 1359 switch (op) 1360 case div: 1361 if acc == INT32_MIN and vs == -1 then 1362 vd = INT32_MIN 1363 else 1364 vd = acc / vs 1365 end 1366 case div.64: 1367 if acc == INT64_MIN and vs == -1 then 1368 vd = INT64_MIN 1369 else 1370 vd = acc / vs 1371 end 1372 case divu: 1373 case divu.64: 1374 vd = acc / vs 1375 case mod: 1376 if acc == INT32_MIN and vs == -1 then 1377 vd = 0 1378 else 1379 vd = acc % vs 1380 end 1381 case mod.64: 1382 if acc == INT64_MIN and vs == -1 then 1383 vd = 0 1384 else 1385 vd = acc % vs 1386 end 1387 case modu: 1388 case modu.64: 1389 vd = acc % vs 1390 instructions: 1391 - sig: div2v v1:out:i32, v2:in:i32 1392 acc: in:i32 1393 format: [op_v1_8_v2_8] 1394 - sig: div2v.64 v1:out:i64, v2:in:i64 1395 acc: in:i64 1396 format: [op_v1_8_v2_8] 1397 - sig: mod2v v1:out:i32, v2:in:i32 1398 acc: in:i32 1399 format: [op_v1_8_v2_8] 1400 - sig: mod2v.64 v1:out:i64, v2:in:i64 1401 acc: in:i64 1402 format: [op_v1_8_v2_8] 1403 - sig: divu2v v1:out:u32, v2:in:u32 1404 acc: in:u32 1405 prefix: unsigned 1406 format: [pref_op_v1_8_v2_8] 1407 - sig: divu2v.64 v1:out:u64, v2:in:u64 1408 acc: in:u64 1409 prefix: unsigned 1410 format: [pref_op_v1_8_v2_8] 1411 - sig: modu2v v1:out:u32, v2:in:u32 1412 acc: in:u32 1413 prefix: unsigned 1414 format: [pref_op_v1_8_v2_8] 1415 - sig: modu2v.64 v1:out:u64, v2:in:u64 1416 acc: in:u64 1417 prefix: unsigned 1418 format: [pref_op_v1_8_v2_8] 1419 1420 - title: Two address binary operation with immediate on accumulator 1421 description: > 1422 Perform specified binary operation on accumulator and immediate, and store the result into accumulator. 1423 Immediate is sign-extended to operand size. 1424 exceptions: 1425 - x_none 1426 verification: 1427 - acc_type 1428 pseudo: | 1429 switch (op) 1430 case addi: 1431 acc = (acc + imm) % 2^32 1432 case subi: 1433 acc = (acc - imm) % 2^32 1434 case muli: 1435 acc = (acc * imm) % 2^32 1436 case andi: 1437 acc = acc & imm 1438 case ori: 1439 acc = acc | imm 1440 case xori: 1441 acc = acc ^ imm 1442 case shli: 1443 acc = (acc << (imm & 0x1f)) % 2^32 1444 case shri: 1445 acc = acc >> (imm & 0x1f) 1446 case ashri: 1447 acc = (acc < 0) ? ~(~acc >> imm & 0x1f) : acc >> imm & 0x1f 1448 instructions: 1449 - sig: addi imm:i32 1450 acc: inout:i32 1451 format: [op_imm_8] 1452 opcode_idx: [0x57] 1453 - sig: subi imm:i32 1454 acc: inout:i32 1455 format: [op_imm_8] 1456 opcode_idx: [0x58] 1457 - sig: muli imm:i32 1458 acc: inout:i32 1459 format: [op_imm_8] 1460 opcode_idx: [0x59] 1461 - sig: andi imm:i32 1462 acc: inout:i32 1463 format: [op_imm_32] 1464 opcode_idx: [0x5a] 1465 - sig: ori imm:i32 1466 acc: inout:i32 1467 format: [op_imm_32] 1468 opcode_idx: [0x5b] 1469 - sig: xori imm:i32 1470 acc: inout:i32 1471 prefix: bit 1472 format: [pref_op_imm_32] 1473 opcode_idx: [0xe] 1474 - sig: shli imm:i32 1475 acc: inout:i32 1476 format: [op_imm_8] 1477 opcode_idx: [0x5c] 1478 - sig: shri imm:i32 1479 acc: inout:i32 1480 format: [op_imm_8] 1481 opcode_idx: [0x5d] 1482 - sig: ashri imm:i32 1483 acc: inout:i32 1484 format: [op_imm_8] 1485 opcode_idx: [0x5e] 1486 1487 - title: Two address binary operation with immediate 1488 description: > 1489 Perform specified binary operation and immediate, and store the result into the register. 1490 Immediate is sign-extended to operand size. 1491 exceptions: 1492 - x_none 1493 verification: 1494 - v1_type 1495 - v2_type 1496 pseudo: | 1497 switch (op) 1498 case addi: 1499 v1 = (v2 + imm) % 2^32 1500 case subi: 1501 v1 = (v2 - imm) % 2^32 1502 case muli: 1503 v1 = (v2 * imm) % 2^32 1504 case andi: 1505 v1 = v2 & imm 1506 case ori: 1507 v1 = v2 | imm 1508 case xori: 1509 v1 = v2 ^ imm 1510 case shli: 1511 v1 = (v2 << (imm & 0x1f)) % 2^32 1512 case shri: 1513 v1 = v2 >> (imm & 0x1f) 1514 case ashri: 1515 v1 = (v2 < 0) ? ~(~v2 >> imm & 0x1f) : v2 >> imm & 0x1f 1516 instructions: 1517 - sig: addiv v1:out:i32, v2:in:i32, imm:i32 1518 acc: none 1519 format: [op_v1_4_v2_4_imm_8] 1520 - sig: subiv v1:out:i32, v2:in:i32, imm:i32 1521 acc: none 1522 format: [op_v1_4_v2_4_imm_8] 1523 - sig: muliv v1:out:i32, v2:in:i32, imm:i32 1524 acc: none 1525 format: [op_v1_4_v2_4_imm_8] 1526 - sig: andiv v1:out:i32, v2:in:i32, imm:i32 1527 acc: none 1528 format: [op_v1_4_v2_4_imm_32] 1529 - sig: oriv v1:out:i32, v2:in:i32, imm:i32 1530 acc: none 1531 format: [op_v1_4_v2_4_imm_32] 1532 - sig: xoriv v1:out:i32, v2:in:i32, imm:i32 1533 acc: none 1534 prefix: bit 1535 format: [pref_op_v1_4_v2_4_imm_32] 1536 - sig: shliv v1:out:i32, v2:in:i32, imm:i32 1537 acc: none 1538 format: [op_v1_4_v2_4_imm_8] 1539 - sig: shriv v1:out:i32, v2:in:i32, imm:i32 1540 acc: none 1541 format: [op_v1_4_v2_4_imm_8] 1542 - sig: ashriv v1:out:i32, v2:in:i32, imm:i32 1543 acc: none 1544 format: [op_v1_4_v2_4_imm_8] 1545 1546 - title: Two address integer division or modulo with immediate on accumulator 1547 description: > 1548 Perform two address integer division or modulo on accumulator and immediate, and store the result into accumulator. 1549 Immediate is sign-extended to operand size. 1550 exceptions: 1551 - x_arith 1552 verification: 1553 - acc_type 1554 pseudo: | 1555 if imm == 0 then 1556 throw ArithmeticException 1557 end 1558 switch(op) 1559 case divi: 1560 if acc == INT32_MIN and imm == -1 then 1561 acc = INT32_MIN 1562 else 1563 acc = acc / imm 1564 end 1565 case modi: 1566 if acc == INT32_MIN and imm == -1 then 1567 acc = 0 1568 else 1569 acc = acc % imm 1570 end 1571 instructions: 1572 - sig: divi imm:i32 1573 acc: inout:i32 1574 format: [op_imm_8] 1575 opcode_idx: [0x5f] 1576 - sig: modi imm:i32 1577 acc: inout:i32 1578 format: [op_imm_8] 1579 opcode_idx: [0x60] 1580 1581 - title: Two address integer division or modulo with immediate 1582 description: > 1583 Perform two address integer division or modulo and immediate, and store the result into the register. 1584 Immediate is sign-extended to operand size. 1585 exceptions: 1586 - x_arith 1587 verification: 1588 - v1_type 1589 - v2_type 1590 pseudo: | 1591 if imm == 0 then 1592 throw ArithmeticException 1593 end 1594 switch(op) 1595 case divi: 1596 if v1 == INT32_MIN and imm == -1 then 1597 v1 = INT32_MIN 1598 else 1599 v1 = v2 / imm 1600 end 1601 case modi: 1602 if v1 == INT32_MIN and imm == -1 then 1603 v1 = 0 1604 else 1605 v1 = v2 % imm 1606 end 1607 instructions: 1608 - sig: diviv v1:out:i32, v2:in:i32, imm:i32 1609 acc: none 1610 format: [op_v1_4_v2_4_imm_8] 1611 - sig: modiv v1:out:i32, v2:in:i32, imm:i32 1612 acc: none 1613 format: [op_v1_4_v2_4_imm_8] 1614 1615 - title: Three address binary operation 1616 description: Perform specified binary operation on two registers, and store the result into accumulator. 1617 exceptions: 1618 - x_none 1619 verification: 1620 - v1_type 1621 - v2_type 1622 pseudo: | 1623 switch (op) 1624 case add: 1625 acc = (vs1 + vs2) % 2^32 1626 case sub: 1627 acc = (vs1 - vs2) % 2^32 1628 case mul: 1629 acc = (vs1 * vs2) % 2^32 1630 case and: 1631 acc = vs1 & vs2 1632 case or: 1633 acc = vs1 | vs2 1634 case xor: 1635 acc = vs1 ^ vs2 1636 case shl: 1637 acc = (vs1 << (vs2 & 0x1f)) % 2^32 1638 case shr: 1639 acc = vs1 >> (vs2 & 0x1f) 1640 case ashr: 1641 acc = (vs1 < 0) ? ~(~vs1 >> vs2 & 0x1f) : vs1 >> vs2 & 0x1f 1642 instructions: 1643 - sig: add v1:in:i32, v2:in:i32 1644 acc: out:i32 1645 format: [op_v1_4_v2_4] 1646 opcode_idx: [0x61] 1647 - sig: sub v1:in:i32, v2:in:i32 1648 acc: out:i32 1649 format: [op_v1_4_v2_4] 1650 opcode_idx: [0x62] 1651 - sig: mul v1:in:i32, v2:in:i32 1652 acc: out:i32 1653 format: [op_v1_4_v2_4] 1654 opcode_idx: [0x63] 1655 - sig: and v1:in:i32, v2:in:i32 1656 acc: out:i32 1657 prefix: bit 1658 format: [pref_op_v1_4_v2_4] 1659 opcode_idx: [0xf] 1660 - sig: or v1:in:i32, v2:in:i32 1661 acc: out:i32 1662 prefix: bit 1663 format: [pref_op_v1_4_v2_4] 1664 opcode_idx: [0x10] 1665 - sig: xor v1:in:i32, v2:in:i32 1666 acc: out:i32 1667 prefix: bit 1668 format: [pref_op_v1_4_v2_4] 1669 opcode_idx: [0x11] 1670 - sig: shl v1:in:i32, v2:in:i32 1671 acc: out:i32 1672 prefix: bit 1673 format: [pref_op_v1_4_v2_4] 1674 opcode_idx: [0x12] 1675 - sig: shr v1:in:i32, v2:in:i32 1676 acc: out:i32 1677 prefix: bit 1678 format: [pref_op_v1_4_v2_4] 1679 opcode_idx: [0x13] 1680 - sig: ashr v1:in:i32, v2:in:i32 1681 acc: out:i32 1682 prefix: bit 1683 format: [pref_op_v1_4_v2_4] 1684 opcode_idx: [0x14] 1685 1686 - title: Three address binary operation with the result in the register 1687 description: Perform specified binary operation on two registers, and store the result into the register. 1688 exceptions: 1689 - x_none 1690 verification: 1691 - v1_type 1692 - v2_type 1693 pseudo: | 1694 switch (op) 1695 case add: 1696 v1 = (v1 + v2) % 2^32 1697 case sub: 1698 v1 = (v1 - v2) % 2^32 1699 case mul: 1700 v1 = (v1 * v2) % 2^32 1701 case and: 1702 v1 = v1 & v2 1703 case or: 1704 v1 = v1 | v2 1705 case xor: 1706 v1 = v1 ^ v2 1707 case shl: 1708 v1 = (v1 << (v2 & 0x1f)) % 2^32 1709 case shr: 1710 v1 = v1 >> (v2 & 0x1f) 1711 case ashr: 1712 v1 = (v1 < 0) ? ~(~v1 >> v2 & 0x1f) : v1 >> v2 & 0x1f 1713 instructions: 1714 - sig: addv v1:inout:i32, v2:in:i32 1715 acc: none 1716 format: [op_v1_4_v2_4] 1717 - sig: subv v1:inout:i32, v2:in:i32 1718 acc: none 1719 format: [op_v1_4_v2_4] 1720 - sig: mulv v1:inout:i32, v2:in:i32 1721 acc: none 1722 format: [op_v1_4_v2_4] 1723 - sig: andv v1:inout:i32, v2:in:i32 1724 acc: none 1725 prefix: bit 1726 format: [pref_op_v1_4_v2_4] 1727 - sig: orv v1:inout:i32, v2:in:i32 1728 acc: none 1729 prefix: bit 1730 format: [pref_op_v1_4_v2_4] 1731 - sig: xorv v1:inout:i32, v2:in:i32 1732 acc: none 1733 prefix: bit 1734 format: [pref_op_v1_4_v2_4] 1735 - sig: shlv v1:inout:i32, v2:in:i32 1736 acc: none 1737 prefix: bit 1738 format: [pref_op_v1_4_v2_4] 1739 - sig: shrv v1:inout:i32, v2:in:i32 1740 acc: none 1741 prefix: bit 1742 format: [pref_op_v1_4_v2_4] 1743 - sig: ashrv v1:inout:i32, v2:in:i32 1744 acc: none 1745 prefix: bit 1746 format: [pref_op_v1_4_v2_4] 1747 1748 - title: Three address integer division or modulo 1749 description: Perform integer division or modulo on two registers, and store the result into accumulator. 1750 exceptions: 1751 - x_arith 1752 verification: 1753 - v1_type 1754 - v2_type 1755 pseudo: | 1756 if vs2 == 0 then 1757 throw ArithmeticException 1758 end 1759 switch(op) 1760 case div: 1761 if vs1 == INT32_MIN and vs2 == -1 then 1762 acc = INT32_MIN 1763 else 1764 acc = vs1 / vs2 1765 end 1766 case mod: 1767 if vs1 == INT32_MIN and vs2 == -1 then 1768 acc = 0 1769 else 1770 acc = vs1 % vs2 1771 end 1772 instructions: 1773 - sig: div v1:in:i32, v2:in:i32 1774 acc: out:i32 1775 format: [op_v1_4_v2_4] 1776 opcode_idx: [0x64] 1777 - sig: mod v1:in:i32, v2:in:i32 1778 acc: out:i32 1779 format: [op_v1_4_v2_4] 1780 opcode_idx: [0x65] 1781 1782 - title: Three address integer division or modulo with the result in the register 1783 description: Perform integer division or modulo on two registers, and store the result into accumulator. 1784 exceptions: 1785 - x_arith 1786 verification: 1787 - v1_type 1788 - v2_type 1789 pseudo: | 1790 if v2 == 0 then 1791 throw ArithmeticException 1792 end 1793 switch(op) 1794 case div: 1795 if v1 == INT32_MIN and v2 == -1 then 1796 v1 = INT32_MIN 1797 else 1798 v1 = v1 / v2 1799 end 1800 case mod: 1801 if v1 == INT32_MIN and v2 == -1 then 1802 v1 = 0 1803 else 1804 v1 = v1 % v2 1805 end 1806 instructions: 1807 - sig: divv v1:inout:i32, v2:in:i32 1808 acc: none 1809 format: [op_v1_4_v2_4] 1810 - sig: modv v1:inout:i32, v2:in:i32 1811 acc: none 1812 format: [op_v1_4_v2_4] 1813 1814 - title: Increment register with immediate 1815 description: > 1816 Increment virtual register by specified immediate. Immediate is sign-extended to operand size. 1817 exceptions: 1818 - x_none 1819 verification: 1820 - v1_i32 1821 pseudo: | 1822 vx = (vx + imm) % 2^32 1823 instructions: 1824 - sig: inci v:inout:i32, imm:i32 1825 acc: none 1826 format: [op_v_4_imm_4] 1827 opcode_idx: [0x66] 1828 1829 - title: Conversions between integer and floating-point types 1830 description: | 1831 Perform specified primitive type conversion of accumulator. 1832 Conversion from floating-point types to integer type is performed by the following rules: 1833 1834 - It is rounding toward zero. 1835 - If converted value is less than minimal value for destination type, then the result is the minimum value for that type. 1836 - If source is negative infinity, then the result is the minimum value for the destination type. 1837 - If converted value is greater than the maximum value for the destination type, then the result is the maximum value for that type. 1838 - If source is positive infinity, then the result is the maximum value for the destination type. 1839 - If source is NaN, then the result is equal to 0. 1840 1841 properties: 1842 - float 1843 exceptions: 1844 - x_none 1845 verification: 1846 - acc_type 1847 pseudo: | 1848 (dest_type) acc = (src_type) acc 1849 instructions: 1850 - sig: i32tof32 1851 acc: inout:i32->f32 1852 prefix: f32 1853 format: [pref_op_none] 1854 opcode_idx: [0xa] 1855 - sig: i32tof64 1856 acc: inout:i32->f64 1857 prefix: cast 1858 format: [pref_op_none] 1859 opcode_idx: [0x0] 1860 - sig: u32tof32 1861 acc: inout:u32->f32 1862 prefix: f32 1863 format: [pref_op_none] 1864 opcode_idx: [0xb] 1865 - sig: u32tof64 1866 acc: inout:u32->f64 1867 prefix: cast 1868 format: [pref_op_none] 1869 opcode_idx: [0x1] 1870 - sig: i64tof32 1871 acc: inout:i64->f32 1872 prefix: f32 1873 format: [pref_op_none] 1874 opcode_idx: [0xc] 1875 - sig: i64tof64 1876 acc: inout:i64->f64 1877 prefix: cast 1878 format: [pref_op_none] 1879 opcode_idx: [0x2] 1880 - sig: u64tof32 1881 acc: inout:u64->f32 1882 prefix: f32 1883 format: [pref_op_none] 1884 opcode_idx: [0xd] 1885 - sig: u64tof64 1886 acc: inout:u64->f64 1887 prefix: cast 1888 format: [pref_op_none] 1889 opcode_idx: [0x3] 1890 - sig: f32tof64 1891 acc: inout:f32->f64 1892 prefix: f32 1893 format: [pref_op_none] 1894 opcode_idx: [0xe] 1895 - sig: f32toi32 1896 acc: inout:f32->i32 1897 prefix: f32 1898 format: [pref_op_none] 1899 opcode_idx: [0xf] 1900 - sig: f32toi64 1901 acc: inout:f32->i64 1902 prefix: f32 1903 format: [pref_op_none] 1904 opcode_idx: [0x10] 1905 - sig: f32tou32 1906 acc: inout:f32->u32 1907 prefix: f32 1908 format: [pref_op_none] 1909 opcode_idx: [0x11] 1910 - sig: f32tou64 1911 acc: inout:f32->u64 1912 prefix: f32 1913 format: [pref_op_none] 1914 opcode_idx: [0x12] 1915 - sig: f64toi32 1916 acc: inout:f64->i32 1917 prefix: cast 1918 format: [pref_op_none] 1919 opcode_idx: [0x4] 1920 - sig: f64toi64 1921 acc: inout:f64->i64 1922 prefix: cast 1923 format: [pref_op_none] 1924 opcode_idx: [0x5] 1925 - sig: f64tou32 1926 acc: inout:f64->u32 1927 prefix: cast 1928 format: [pref_op_none] 1929 opcode_idx: [0x6] 1930 - sig: f64tou64 1931 acc: inout:f64->u64 1932 prefix: cast 1933 format: [pref_op_none] 1934 opcode_idx: [0x7] 1935 - sig: f64tof32 1936 acc: inout:f64->f32 1937 prefix: f32 1938 format: [pref_op_none] 1939 opcode_idx: [0x13] 1940 1941 - title: Conversions from integer types to u1 1942 description: | 1943 Conversion from integer types to u1 is performed by the following rules: 1944 1945 - If converted integer is not equal to zero, then the result is 1. 1946 - Otherwise, the result is 0. 1947 1948 exceptions: 1949 - x_none 1950 verification: 1951 - acc_type 1952 pseudo: | 1953 (dest_type) acc = (src_type) acc 1954 instructions: 1955 - sig: i32tou1 1956 acc: inout:i32->u1 1957 prefix: cast 1958 format: [pref_op_none] 1959 opcode_idx: [0x8] 1960 - sig: i64tou1 1961 acc: inout:i64->u1 1962 prefix: cast 1963 format: [pref_op_none] 1964 opcode_idx: [0x9] 1965 - sig: u32tou1 1966 acc: inout:u32->u1 1967 prefix: cast 1968 format: [pref_op_none] 1969 opcode_idx: [0xa] 1970 - sig: u64tou1 1971 acc: inout:u64->u1 1972 prefix: cast 1973 format: [pref_op_none] 1974 opcode_idx: [0xb] 1975 1976 - title: Integer truncations and extensions 1977 description: > 1978 Perform specified integer extension or truncations of accumulator. 1979 Truncations discard all but N lowest-order bits, where N is the bit size of the destination type. 1980 If extension bytecode treats its source as signed integer, then the value is sign-extended to destination type. 1981 If extension bytecode treats its source as unsigned integer, then the value is zero-extended to destination type. 1982 exceptions: 1983 - x_none 1984 verification: 1985 - acc_type 1986 pseudo: | 1987 (dest_type) acc = (src_type) acc 1988 instructions: 1989 - sig: i32toi64 1990 acc: inout:i32->i64 1991 prefix: cast 1992 format: [pref_op_none] 1993 opcode_idx: [0xc] 1994 - sig: i32toi16 1995 acc: inout:i32->i16 1996 prefix: cast 1997 format: [pref_op_none] 1998 opcode_idx: [0xd] 1999 - sig: i32tou16 2000 acc: inout:i32->u16 2001 prefix: cast 2002 format: [pref_op_none] 2003 opcode_idx: [0xe] 2004 - sig: i32toi8 2005 acc: inout:i32->i8 2006 prefix: cast 2007 format: [pref_op_none] 2008 opcode_idx: [0xf] 2009 - sig: i32tou8 2010 acc: inout:i32->u8 2011 prefix: cast 2012 format: [pref_op_none] 2013 opcode_idx: [0x10] 2014 - sig: i64toi32 2015 acc: inout:i64->i32 2016 prefix: cast 2017 format: [pref_op_none] 2018 opcode_idx: [0x11] 2019 - sig: u32toi64 2020 acc: inout:u32->i64 2021 prefix: cast 2022 format: [pref_op_none] 2023 opcode_idx: [0x12] 2024 - sig: u32toi16 2025 acc: inout:u32->i16 2026 prefix: cast 2027 format: [pref_op_none] 2028 opcode_idx: [0x13] 2029 - sig: u32tou16 2030 acc: inout:u32->u16 2031 prefix: cast 2032 format: [pref_op_none] 2033 opcode_idx: [0x14] 2034 - sig: u32toi8 2035 acc: inout:u32->i8 2036 prefix: cast 2037 format: [pref_op_none] 2038 opcode_idx: [0x15] 2039 - sig: u32tou8 2040 acc: inout:u32->u8 2041 prefix: cast 2042 format: [pref_op_none] 2043 opcode_idx: [0x16] 2044 - sig: u64toi32 2045 acc: inout:u64->i32 2046 prefix: cast 2047 format: [pref_op_none] 2048 opcode_idx: [0x17] 2049 - sig: u64tou32 2050 acc: inout:u64->u32 2051 prefix: cast 2052 format: [pref_op_none] 2053 opcode_idx: [0x18] 2054 2055 - title: Load from array 2056 description: > 2057 Load an element from array using accumulator as an index and put it into accumulator. 2058 If the size of an element is smaller then 32 bits, then it is zero or 2059 sign-extended (depending on bytecode) to i32. 2060 verification: 2061 - v1_array_type 2062 - acc_i32 2063 exceptions: 2064 - x_null 2065 - x_bounds 2066 pseudo: | 2067 if vs == null then 2068 throw NullPointerException 2069 end 2070 if acc < 0 || acc >= len(vs) then 2071 throw ArrayIndexOutOfBoundsException 2072 end 2073 if op == ldarr.8 then 2074 acc = i8toi32(vs[acc]) 2075 else if op == ldarru.8 then 2076 acc = u8toi32(vs[acc]) 2077 else if op == ldarr.16 then 2078 acc = i16toi32(vs[acc]) 2079 else if op == ldarru.16 then 2080 acc = u16toi32(vs[acc]) 2081 else 2082 acc = vs[acc] 2083 end 2084 instructions: 2085 - sig: ldarr.8 v:in:i8[] 2086 acc: inout:i32 2087 format: [op_v_8] 2088 opcode_idx: [0x67] 2089 - sig: ldarru.8 v:in:u8[] 2090 acc: inout:i32 2091 format: [op_v_8] 2092 opcode_idx: [0x68] 2093 - sig: ldarr.16 v:in:i16[] 2094 acc: inout:i32 2095 format: [op_v_8] 2096 opcode_idx: [0x69] 2097 - sig: ldarru.16 v:in:u16[] 2098 acc: inout:i32 2099 format: [op_v_8] 2100 opcode_idx: [0x6a] 2101 - sig: ldarr v:in:i32[] 2102 acc: inout:i32 2103 format: [op_v_8] 2104 opcode_idx: [0x6b] 2105 - sig: ldarr.64 v:in:i64[] 2106 acc: inout:i32->i64 2107 format: [op_v_8] 2108 opcode_idx: [0x6c] 2109 - sig: fldarr.32 v:in:f32[] 2110 acc: inout:i32->f32 2111 format: [op_v_8] 2112 opcode_idx: [0x6d] 2113 properties: [float] 2114 - sig: fldarr.64 v:in:f64[] 2115 acc: inout:i32->f64 2116 format: [op_v_8] 2117 opcode_idx: [0x6e] 2118 properties: [float] 2119 - sig: ldarr.obj v:in:ref[] 2120 acc: inout:i32->ref 2121 format: [op_v_8] 2122 opcode_idx: [0x6f] 2123 2124 - title: Store to array 2125 description: > 2126 Store the accumulator content into the array slot pointed by index. 2127 If the size of an element to store is less than 32, then the accumulator 2128 content is truncated to storage size before storing. 2129 verification: 2130 - v1_array_type 2131 - v2_i32 2132 - acc_type 2133 exceptions: 2134 - x_null 2135 - x_bounds 2136 - x_store 2137 pseudo: | 2138 if vs1 == null then 2139 throw NullPointerException 2140 end 2141 if vs2 < 0 || vs2 >= len(vs1) then 2142 throw ArrayIndexOutOfBoundsException 2143 end 2144 if op == starr.obj && !has_type(acc, component_type(vs1)) 2145 throw ArrayStoreException 2146 end 2147 if op == starr.8 then 2148 vs1[vs2] = truncateto8(acc) 2149 else if op == starr.16 then 2150 vs1[vs2] = truncateto16(acc) 2151 else 2152 vs1[vs2] = acc 2153 end 2154 instructions: 2155 - sig: starr.8 v1:in:i8[], v2:in:i32 2156 acc: in:i8 2157 format: [op_v1_4_v2_4] 2158 opcode_idx: [0x70] 2159 - sig: starr.16 v1:in:i16[], v2:in:i32 2160 acc: in:i16 2161 format: [op_v1_4_v2_4] 2162 opcode_idx: [0x71] 2163 - sig: starr v1:in:i32[], v2:in:i32 2164 acc: in:i32 2165 format: [op_v1_4_v2_4] 2166 opcode_idx: [0x72] 2167 - sig: starr.64 v1:in:i64[], v2:in:i32 2168 acc: in:i64 2169 format: [op_v1_4_v2_4] 2170 opcode_idx: [0x73] 2171 - sig: fstarr.32 v1:in:f32[], v2:in:i32 2172 acc: in:f32 2173 format: [op_v1_4_v2_4] 2174 opcode_idx: [0x74] 2175 properties: [float] 2176 - sig: fstarr.64 v1:in:f64[], v2:in:i32 2177 acc: in:f64 2178 format: [op_v1_4_v2_4] 2179 opcode_idx: [0x75] 2180 properties: [float] 2181 - sig: starr.obj v1:in:ref[], v2:in:i32 2182 acc: in:ref 2183 format: [op_v1_4_v2_4] 2184 opcode_idx: [0x76] 2185 2186 - title: Array length 2187 description: Get length of an array and put it into accumulator. 2188 verification: 2189 - v1_array 2190 exceptions: 2191 - x_null 2192 pseudo: | 2193 if x == null then 2194 throw NullPointerException 2195 end 2196 acc = len(vs) 2197 instructions: 2198 - sig: lenarr v:in:top[] 2199 acc: out:i32 2200 format: [op_v_8] 2201 opcode_idx: [0x77] 2202 2203 - title: Create new array 2204 description: > 2205 Create a new single-dimensional array of given type and size and put a reference to it into register. 2206 Elements of array are initialized to a default value, i.e., 0 for primitive types and null for objects. 2207 verification: 2208 - type_id_array 2209 - v2_i32 2210 exceptions: 2211 - x_negsize 2212 - x_oom 2213 properties: 2214 - type_id 2215 - language_type 2216 - initialize_type 2217 pseudo: | 2218 if v2 < 0 then 2219 throw NegativeArraySizeException 2220 end 2221 type = resolve(type_id) 2222 v1 = new_array(v2, type) 2223 if not initialized(type) 2224 initialize(type) 2225 end 2226 if v1 == null then 2227 throw OutOfMemoryError 2228 end 2229 instructions: 2230 - sig: newarr v1:out:ref, v2:in:i32, type_id 2231 acc: none 2232 format: [op_v1_4_v2_4_id_16] 2233 opcode_idx: [0x78] 2234 2235 - title: Create new object 2236 description: | 2237 Resolve class type from type_id, allocate memory for an object, 2238 initialize its fields with their default values (i.e., 0 for primitives 2239 and null for objects), and put a reference to the newly created object 2240 into the register. The object must be initialized by calling the 2241 initialization method before further usage. 2242 verification: 2243 - type_id_object 2244 exceptions: 2245 - x_oom 2246 properties: 2247 - type_id 2248 - initialize_type 2249 pseudo: | 2250 type = resolve(type_id) 2251 if not initialized(type) 2252 initialize(type) 2253 end 2254 v = new_instance(type) 2255 if v == null then 2256 throw OutOfMemoryError 2257 end 2258 instructions: 2259 - sig: newobj v:out:ref, type_id 2260 acc: none 2261 format: [op_v_8_id_16] 2262 opcode_idx: [0x79] 2263 2264 - title: Create new object and call initializer 2265 description: > 2266 Resolve class type from initializer method_id, allocate memory for an 2267 object, initialize its fields with their default values (i.e., 0 for 2268 primitives and null for objects), call specified initializer, and put 2269 a reference to the newly created object into accumulator. 2270 method_id must resolve to an initializer. Non-range instructions can be 2271 used to pass up to 4 arguments. Unused register slot values are to be 2272 discarded, and corresponding registers are not to be passed to initializer). 2273 Range kinds of instruction is to be used for methods with more arguments. 2274 Such instructions take the required number of arguments starting from 2275 'vs' register. 2276 verification: 2277 - method_id_non_static 2278 - method_id_accessible 2279 - method_init_obj 2280 - compatible_arguments 2281 exceptions: 2282 - x_abstract 2283 - x_oom 2284 - x_call 2285 properties: 2286 - method_id 2287 - call 2288 - initialize_type 2289 - init_obj 2290 - short_long_range 2291 pseudo: | 2292 init, type = resolve(method_id) 2293 if not initialized(type) 2294 initialize(type) 2295 end 2296 acc = new_instance(type) 2297 if acc == null then 2298 throw OutOfMemoryError 2299 end 2300 init(acc, args) 2301 instructions: 2302 - sig: initobj.short method_id, v1:in:none, v2:in:none 2303 acc: out:ref 2304 format: [op_v1_4_v2_4_id_16] 2305 opcode_idx: [0x7a] 2306 - sig: initobj method_id, v1:in:none, v2:in:none, v3:in:none, v4:in:none 2307 acc: out:ref 2308 format: [op_v1_4_v2_4_v3_4_v4_4_id_16] 2309 opcode_idx: [0x7b] 2310 - sig: initobj.range method_id, v:in:none 2311 acc: out:ref 2312 format: [op_v_8_id_16] 2313 opcode_idx: [0x7c] 2314 2315 - title: Get field from object to accumulator 2316 description: > 2317 Get field value from an object by field id and put it into accumulator. 2318 For a non-object variant, the size of the field is determined by the 2319 field_id. The most significant bits are sign- or unsigned-extended 2320 based on the field type to fit accumulator size. If field type size is 2321 less than 32, then the loaded value is sign- or zero-extended to i32 2322 depending on field type. 2323 verification: 2324 - v1_object 2325 - field_id_non_static 2326 - field_id_size 2327 properties: 2328 - field_id 2329 exceptions: 2330 - x_null 2331 pseudo: | 2332 if vs == null then 2333 throw NullPointerException 2334 end 2335 field = resolve(field_id) 2336 if op == ldobj and size(field) < 32 then 2337 acc = extendto32(vs.get(field)) 2338 else 2339 acc = vs.get(field) 2340 end 2341 instructions: 2342 - sig: ldobj v:in:ref, field_id 2343 acc: out:b32 2344 format: [op_v_8_id_16] 2345 opcode_idx: [0x7d] 2346 - sig: ldobj.64 v:in:ref, field_id 2347 acc: out:b64 2348 format: [op_v_8_id_16] 2349 opcode_idx: [0x7e] 2350 - sig: ldobj.obj v:in:ref, field_id 2351 acc: out:ref 2352 format: [op_v_8_id_16] 2353 opcode_idx: [0x7f] 2354 2355 - title: Store accumulator content into object field 2356 description: > 2357 Store the accumulator content into object field by field_id. For 2358 a non-object variant, the size of the actually stored value is determined 2359 by field_id, while other accumulator bits are discarded. 2360 If field type size is less than 32, then the accumulator content is 2361 truncated to storage size before storing. 2362 verification: 2363 - v1_object 2364 - field_id_non_static 2365 - field_id_size 2366 - acc_type 2367 properties: 2368 - field_id 2369 exceptions: 2370 - x_null 2371 pseudo: | 2372 if vs == null then 2373 throw NullPointerException 2374 end 2375 field = resolve(field_id) 2376 if op == stobj and size(field) < 32 then 2377 vs.set(field, truncate(field, acc)) 2378 else 2379 vs.set(field, acc) 2380 end 2381 instructions: 2382 - sig: stobj v:in:ref, field_id 2383 acc: in:b32 2384 format: [op_v_8_id_16] 2385 opcode_idx: [0x80] 2386 - sig: stobj.64 v:in:ref, field_id 2387 acc: in:b64 2388 format: [op_v_8_id_16] 2389 opcode_idx: [0x81] 2390 - sig: stobj.obj v:in:ref, field_id 2391 acc: in:ref 2392 format: [op_v_8_id_16] 2393 opcode_idx: [0x82] 2394 2395 - title: Get field from object to register 2396 description: > 2397 Get field value from an object by field id and put it into register. 2398 For a non-object variant, the size of the field is determined by the 2399 field_id, and the most significant bits are sign- or unsigned-extended 2400 based on the field type to fit register size. If field type size is less 2401 than 32, then the loaded value is sign- or zero-extended to i32 2402 depending on field type. 2403 verification: 2404 - v2_object 2405 - field_id_non_static 2406 - field_id_size 2407 properties: 2408 - field_id 2409 exceptions: 2410 - x_null 2411 pseudo: | 2412 if v2 == null then 2413 throw NullPointerException 2414 end 2415 field = resolve(field_id) 2416 if op == ldobj and size(field) < 32 then 2417 v1 = extendto32(v2.get(field)) 2418 else 2419 v1 = v2.get(field) 2420 end 2421 instructions: 2422 - sig: ldobj.v v1:out:b32, v2:in:ref, field_id 2423 acc: none 2424 format: [op_v1_4_v2_4_id_16] 2425 opcode_idx: [0x83] 2426 - sig: ldobj.v.64 v1:out:b64, v2:in:ref, field_id 2427 acc: none 2428 format: [op_v1_4_v2_4_id_16] 2429 opcode_idx: [0x84] 2430 - sig: ldobj.v.obj v1:out:ref, v2:in:ref, field_id 2431 acc: none 2432 format: [op_v1_4_v2_4_id_16] 2433 opcode_idx: [0x85] 2434 2435 - title: Store register content into object field 2436 description: > 2437 Store register content into object field by field_id. For a non-object 2438 variant the size of the actually stored value is determined by field_id, 2439 while other register bits are discarded. 2440 If field type size is less than 32, then the register content is truncated 2441 to storage size before storing. 2442 verification: 2443 - v1_type 2444 - v2_object 2445 - field_id_non_static 2446 - field_id_size 2447 properties: 2448 - field_id 2449 exceptions: 2450 - x_null 2451 pseudo: | 2452 if v2 == null then 2453 throw NullPointerException 2454 end 2455 field = resolve(field_id) 2456 if op == stobj and size(field) < 32 then 2457 v2.set(field, truncate(field, v1)) 2458 else 2459 v2.set(field, v1) 2460 end 2461 instructions: 2462 - sig: stobj.v v1:in:b32, v2:in:ref, field_id 2463 acc: none 2464 format: [op_v1_4_v2_4_id_16] 2465 opcode_idx: [0x86] 2466 - sig: stobj.v.64 v1:in:b64, v2:in:ref, field_id 2467 acc: none 2468 format: [op_v1_4_v2_4_id_16] 2469 opcode_idx: [0x87] 2470 - sig: stobj.v.obj v1:in:ref, v2:in:ref, field_id 2471 acc: none 2472 format: [op_v1_4_v2_4_id_16] 2473 opcode_idx: [0x88] 2474 2475 - title: Get static field 2476 description: > 2477 Get static field value by field_id and put it into accumulator. For a 2478 non-object variant, the size of the field is determined by field_id, the 2479 most significant bits are sign- or unsigned-extended based on field type 2480 to fit accumulator size. 2481 If field size is less then 32, then the result is sign- or 2482 unsigned-extended to i32 depending on field type. 2483 verification: 2484 - field_id_static 2485 - field_id_size 2486 properties: 2487 - static_field_id 2488 - initialize_type 2489 exceptions: 2490 - x_init 2491 pseudo: | 2492 field, type = resolve(field_id) 2493 if not initialized(type) 2494 initialize(type) 2495 end 2496 if op == ldstatic and size(field) < 32 then 2497 acc = extendto32(get_static(field)) 2498 else 2499 acc = get_static(field) 2500 end 2501 instructions: 2502 - sig: ldstatic field_id 2503 acc: out:b32 2504 format: [op_id_16] 2505 opcode_idx: [0x89] 2506 - sig: ldstatic.64 field_id 2507 acc: out:b64 2508 format: [op_id_16] 2509 opcode_idx: [0x8a] 2510 - sig: ldstatic.obj field_id 2511 acc: out:ref 2512 format: [op_id_16] 2513 opcode_idx: [0x8b] 2514 2515 - title: Store to static field 2516 description: > 2517 Store accumulator content into static field by field_id. For a non-object 2518 variant the size of the actually stored value is determined by field_id, other 2519 accumulator bits are discarded. If field type size is less than 32, then 2520 accumulator content is truncated to field size before storing. 2521 verification: 2522 - field_id_static 2523 - field_id_size 2524 - acc_type 2525 properties: 2526 - static_field_id 2527 - initialize_type 2528 exceptions: 2529 - x_init 2530 pseudo: | 2531 field, type = resolve(field_id) 2532 if not initialized(type) 2533 initialize(type) 2534 end 2535 if op == ststatic and size(field) < 32 then 2536 set_static(field, truncate(field, acc)) 2537 else 2538 set_static(field, acc) 2539 end 2540 instructions: 2541 - sig: ststatic field_id 2542 acc: in:b32 2543 format: [op_id_16] 2544 opcode_idx: [0x8c] 2545 - sig: ststatic.64 field_id 2546 acc: in:b64 2547 format: [op_id_16] 2548 opcode_idx: [0x8d] 2549 - sig: ststatic.obj field_id 2550 acc: in:ref 2551 format: [op_id_16] 2552 opcode_idx: [0x8e] 2553 2554 - title: Return value from method 2555 description: > 2556 Return from the current method, i.e., restore the frame of method invoker 2557 and return control to the invoker. Return value must be in accumulator. 2558 verification: 2559 - acc_return_type 2560 exceptions: 2561 - x_none 2562 properties: 2563 - return 2564 pseudo: | 2565 return acc 2566 instructions: 2567 - sig: return 2568 acc: in:b32 2569 format: [op_none] 2570 opcode_idx: [0x8f] 2571 - sig: return.64 2572 acc: in:b64 2573 format: [op_none] 2574 opcode_idx: [0x90] 2575 - sig: return.obj 2576 acc: in:ref 2577 format: [op_none] 2578 opcode_idx: [0x91] 2579 2580 - title: Return from a void method 2581 description: > 2582 Return from the current method, i.e., restore the frame of method invoker 2583 and return control to the invoker. Caller must treat accumulator value as 2584 undefined, and cannot use it until accumulator in the caller frame is 2585 defined. 2586 verification: 2587 - none 2588 exceptions: 2589 - x_none 2590 properties: 2591 - return 2592 pseudo: | 2593 return 2594 instructions: 2595 - sig: return.void 2596 acc: none 2597 format: [op_none] 2598 opcode_idx: [0x92] 2599 2600 - title: Throw exception 2601 description: > 2602 Throw an exception located in register. The current method is searched 2603 for the first exception handler that matches the class of exception. If 2604 exception handler is found, then control is passed to the exception 2605 handler. If no exception handler is found, then the frame of invoker is 2606 restored. If such frame exists, then the exception is re-thrown. 2607 If no such frame exists, then the current VM thread exits. 2608 verification: 2609 - v1_throw_type 2610 exceptions: 2611 - x_null 2612 - x_throw 2613 pseudo: | 2614 if vs == null then 2615 throw NullPointerException 2616 end 2617 throw vs 2618 instructions: 2619 - sig: throw v:in:ref 2620 acc: none 2621 format: [op_v_8] 2622 opcode_idx: [0x93] 2623 2624 - title: Check cast 2625 description: > 2626 Resolve object type by specified id; if an object in accumulator can be 2627 cast to the resolved type, then the accumulator content remains unchanged. 2628 Otherwise, ClassCastException is thrown. 2629 Object of type O can be cast to type T if O is the same as T or is a 2630 subtype of T. For arrays, O can be cast to T if T is a root type in type 2631 hierarchy, or array elements of T and O are the same, or O is a subtype 2632 of a T array element. 2633 'null' object reference can be cast to every type. 2634 verification: 2635 - type_id_any_object 2636 - acc_obj_or_null 2637 exceptions: 2638 - x_cast 2639 properties: 2640 - type_id 2641 pseudo: | 2642 type = resolve(type_id) 2643 if acc != null and !has_type(acc, type) then 2644 throw ClassCastException 2645 end 2646 instructions: 2647 - sig: checkcast type_id 2648 acc: in:ref 2649 format: [op_id_16] 2650 opcode_idx: [0x94] 2651 2652 - title: Is instance 2653 description: > 2654 Resolve object type by specified id, and if an object in accumulator is 2655 an instance of the resolved type, then put 1 into accumulator. Otherwise, 2656 put 0. 2657 Object of type O is instance of type T if O is the same as T, or is a 2658 subtype of T. For arrays, T must be a root type in type hierarchy, or 2659 array elements of T and O are the same, or O is a subtype of a T 2660 array element. 2661 'null' object is not an instance of any class. 2662 verification: 2663 - type_id_any_object 2664 - acc_obj_or_null 2665 exceptions: 2666 - x_classdef 2667 properties: 2668 - type_id 2669 pseudo: | 2670 type = resolve(type_id) 2671 if acc == null or !has_type(acc, type) then 2672 acc = 0 2673 else 2674 acc = 1 2675 end 2676 instructions: 2677 - sig: isinstance type_id 2678 acc: inout:ref->i32 2679 format: [op_id_16] 2680 opcode_idx: [0x95] 2681 2682 - title: Static call 2683 description: > 2684 Call the indicated static method, i.e., create new frame, pass values of 2685 arguments, and continue the execution from the first instruction of a 2686 method. 2687 Callee must treat the accumulator value as undefined, and cannot use it 2688 until accumulator in the new frame is defined. 2689 Result (if any) is returned in accumulator (see 'Calling sequence' 2690 for more details). 2691 Method, its class, and the number of arguments is resolved by a given 2692 method_id in runtime constant-pool. 2693 Arguments are passed in source registers in the same order as in the 2694 method signature. 2695 Non-range instructions can be used to pass up to 4 arguments (unused 2696 register slot values are discarded, and corresponding registers are not 2697 passed to the callee). 2698 Range kind of instructions are to be used for methods with more arguments 2699 Such instructions take the required number of arguments starting from 2700 'vs' register. 2701 verification: 2702 - method_id_static 2703 - method_id_non_abstract 2704 - compatible_arguments 2705 properties: 2706 - static_method_id 2707 - call 2708 - initialize_type 2709 - short_long_range 2710 exceptions: 2711 - x_call 2712 pseudo: | 2713 if not initialized(type) 2714 initialize(type) 2715 end 2716 acc = call(method, args) 2717 instructions: 2718 - sig: call.short method_id, v1:in:top, v2:in:top 2719 acc: out:top 2720 format: [op_v1_4_v2_4_id_16] 2721 opcode_idx: [0x96] 2722 - sig: call method_id, v1:in:top, v2:in:top, v3:in:top, v4:in:top 2723 acc: out:top 2724 format: [op_v1_4_v2_4_v3_4_v4_4_id_16] 2725 opcode_idx: [0x97] 2726 - sig: call.range method_id, v:in:top 2727 acc: out:top 2728 format: [op_v_8_id_16] 2729 opcode_idx: [0x98] 2730 2731 - title: Static call with accumulator as input 2732 description: > 2733 Call the indicated static method, i.e., create a new frame, pass values 2734 of arguments, and continue the execution from the first instruction of a 2735 method. 2736 Callee must treat the accumulator value as undefined, and cannot use it 2737 until accumulator in the new frame is defined. 2738 Result (if any) is returned in accumulator (see 'Calling sequence' for 2739 more details). 2740 Method, its class, and the number of arguments is resolved by a given 2741 method_id in runtime constant-pool. 2742 Arguments are passed in source registers in the same order as in the 2743 method signature. 2744 Non-range instructions can be used to pass up to 4 arguments (unused 2745 register slot values are discarded, and corresponding registers are not 2746 passed to the callee). 2747 Immediate operand encodes a position starting from 0 on which accumulator 2748 is passed. 2749 verification: 2750 - method_id_static 2751 - method_id_non_abstract 2752 - compatible_arguments 2753 properties: 2754 - static_method_id 2755 - call 2756 - short_long_range 2757 exceptions: 2758 - x_call 2759 pseudo: | 2760 args = [] 2761 for (i = 0; i < 4; ++i) 2762 if (i < imm) then 2763 args[i] = regs[i] 2764 else if (i == imm) then 2765 args[i] = acc 2766 else 2767 args[i] = regs[i - 1] 2768 end 2769 end 2770 method = resolve(method_id) 2771 acc = call(method, args) 2772 instructions: 2773 - sig: call.acc.short method_id, v:in:top, imm:u1 2774 acc: inout:top 2775 format: [op_v_4_imm_4_id_16] 2776 opcode_idx: [0x99] 2777 - sig: call.acc method_id, v1:in:top, v2:in:top, v3:in:top, imm:u2 2778 acc: inout:top 2779 format: [op_v1_4_v2_4_v3_4_imm_4_id_16] 2780 opcode_idx: [0x9a] 2781 2782 - title: Virtual calls 2783 description: > 2784 Call the indicated virtual method, i.e., create a new frame, pass values 2785 of arguments, and continue the execution from the first instruction of a 2786 method. 2787 Callee must treat the accumulator value as undefined, and cannot use it 2788 until accumulator in the new frame is defined. 2789 Result (if any) is returned in accumulator (see 'Calling sequence' for 2790 more details). 2791 Method, its class, and the number of arguments is resolved by a given 2792 method_id in runtime constant-pool based on object reference using 2793 language-specific semantics (currently only Java virtual methods are 2794 supported, further extensions are TBD). 2795 Object reference is passed in the first source register, arguments are 2796 passed starting from the second source register in the same order as in 2797 the method signature. 2798 Non-range instructions can be used to pass up to 4 arguments (including 2799 object reference). 2800 Unused register slot values are discarded, and corresponding registers 2801 are not passed to the callee). 2802 For methods with more arguments, range kinds of instruction are to be used. 2803 The instructions take the required number of arguments starting from 2804 'vs' register (including object reference). 2805 verification: 2806 - compatible_arguments 2807 - method_id_accessible 2808 exceptions: 2809 - x_null 2810 - x_abstract 2811 - x_call 2812 properties: 2813 - method_id 2814 - call 2815 - call_virt 2816 - short_long_range 2817 pseudo: | 2818 if args[0] == null then 2819 throw NullPointerException 2820 end 2821 method = resolve(method_id) 2822 if is_abstract(method) then 2823 throw AbstractMethodError 2824 end 2825 acc = call(method, args) 2826 instructions: 2827 - sig: call.virt.short method_id, v1:in:top, v2:in:top 2828 acc: out:top 2829 format: [op_v1_4_v2_4_id_16] 2830 opcode_idx: [0x9b] 2831 - sig: call.virt method_id, v1:in:top, v2:in:top, v3:in:top, v4:in:top 2832 acc: out:top 2833 format: [op_v1_4_v2_4_v3_4_v4_4_id_16] 2834 opcode_idx: [0x9c] 2835 - sig: call.virt.range method_id, v:in:top 2836 acc: out:top 2837 format: [op_v_8_id_16] 2838 opcode_idx: [0x9d] 2839 2840 - title: Virtual calls with accumulator as input 2841 description: > 2842 Call the indicated virtual method, i.e., create a new frame, pass values 2843 of arguments, and continue the execution from the first instruction of a 2844 method. 2845 Callee must treat the accumulator value as undefined, and cannot use it 2846 until accumulator in the new frame is defined. 2847 Result (if any) is returned in accumulator (see 'Calling sequence' for 2848 more details). 2849 Method, its class, and the number of arguments is resolved by a given 2850 method_id in runtime constant-pool based on object reference using 2851 language-specific semantics (currently only Java virtual methods are 2852 supported, further extensions are TBD). 2853 Object reference is passed in the first source register, arguments are 2854 passed starting from the second source register in the same order as 2855 in the method signature. 2856 Non-range instructions can be used to pass up to 4 arguments (including 2857 object reference). Unused register slot values are discarded, and 2858 corresponding registers are not passed to the callee). 2859 Immediate operand encodes a position starting from 0 on which accumulator 2860 is passed. 2861 verification: 2862 - compatible_arguments 2863 - method_id_accessible 2864 exceptions: 2865 - x_null 2866 - x_abstract 2867 - x_call 2868 properties: 2869 - method_id 2870 - call 2871 - call_virt 2872 - short_long_range 2873 pseudo: | 2874 args = [] 2875 for (i = 0; i < 4; ++i) 2876 if (i < imm) then 2877 args[i] = regs[i] 2878 else if (i == imm) then 2879 args[i] = acc 2880 else 2881 args[i] = regs[i - 1] 2882 end 2883 end 2884 if args[0] == null then 2885 throw NullPointerException 2886 end 2887 method = resolve(method_id) 2888 if is_abstract(method) then 2889 throw AbstractMethodError 2890 end 2891 acc = call(method, args) 2892 instructions: 2893 - sig: call.virt.acc.short method_id, v:in:top, imm:u1 2894 acc: inout:top 2895 format: [op_v_4_imm_4_id_16] 2896 opcode_idx: [0x9e] 2897 - sig: call.virt.acc method_id, v1:in:top, v2:in:top, v3:in:top, imm:u2 2898 acc: inout:top 2899 format: [op_v1_4_v2_4_v3_4_imm_4_id_16] 2900 opcode_idx: [0x9f] 2901 2902 - title: Dynamic move register-to-register 2903 description: > 2904 Move 'any' values between registers 2905 verification: 2906 - valid_in_dynamic_context 2907 exceptions: 2908 - x_none 2909 properties: 2910 - dynamic 2911 pseudo: | 2912 vd = vs 2913 instructions: 2914 - sig: mov.dyn v1:out:any, v2:in:any 2915 acc: none 2916 format: [op_v1_8_v2_8, op_v1_16_v2_16] 2917 opcode_idx: [0xa0, 0xa1] 2918 2919 - title: Dynamic load accumulator from register 2920 description: > 2921 Move 'any' value from register to accumulator 2922 verification: 2923 - valid_in_dynamic_context 2924 exceptions: 2925 - x_none 2926 properties: 2927 - dynamic 2928 pseudo: | 2929 acc = v 2930 instructions: 2931 - sig: lda.dyn v:in:any 2932 acc: out:any 2933 format: [op_v_8] 2934 opcode_idx: [0xa2] 2935 2936 - title: Dynamic store accumulator 2937 description: > 2938 Move 'any' value from accumulator to register 2939 verification: 2940 - valid_in_dynamic_context 2941 exceptions: 2942 - x_none 2943 properties: 2944 - dynamic 2945 pseudo: | 2946 v = acc 2947 instructions: 2948 - sig: sta.dyn v:out:any 2949 acc: in:any 2950 format: [op_v_8] 2951 opcode_idx: [0xa3] 2952 2953 - title: Dynamic load accumulator from immediate 2954 description: > 2955 Move immediate as 'any' value to accumulator 2956 verification: 2957 - valid_in_dynamic_context 2958 exceptions: 2959 - x_none 2960 properties: 2961 - dynamic 2962 pseudo: | 2963 acc = imm 2964 instructions: 2965 - sig: ldai.dyn imm:i32 2966 acc: out:any 2967 format: [op_imm_32] 2968 opcode_idx: [0xa4] 2969 - sig: fldai.dyn imm:f64 2970 acc: out:any 2971 format: [op_imm_64] 2972 opcode_idx: [0xa5] 2973 properties: [float, dynamic] 2974