Continued from Target Languages Concordance part II
Instruction lists from each platform
When instruction counts are given, we count mnemonics. Sometimes similar mnemonics are grouped together and counted as one.
RISC-V instruction list
RV32I (base 32-bit integer set; 47 instructions):
- constant loads: (pseudoinstruction for loading constants using addi or ori) lui auipc
- add, subtract: add addi sub
- shifts: sll slli srl srli sra srai
- logical: and andi or ori xor xori
- compares: slt slti sltu sltiu
- loads and stores: lw lh lhu lb lbu sw sh sb
- atomics and sync: fence fence.i
- jumps: jal jalr
- conditional branches: beq bne blt bge bltu bgeu
- misc control flow: (unnamed all-zero illegal pseudoinstruction) (nop pseudoinstruction)
- misc: ecall ebreak
- misc Control and Status Register: CSRRW (Atomic Read/Write CSR), CSRRS (Atomic Read and Set Bits in CSR), CSRRC (Atomic Read and Clear Bits in CSR), CSRRWI (CSRRW immediate), CSRRSI (CSRRS immediate), CSRRCI (CSRRC immediate)
- misc (RV32I Counters pseudo-instructions (note: these are in RV32I but not in RV32E): RDCYCLE RDCYCLEH, RDTIME RDTIMEH, RDINSTRRET RDINSTRRETH)
RV64I (base 64-bit integer set; 59 instructions) (note: RV64I includes everything in RV32I, but adapted for 64-bit, plus these) (12 new instructions and 3 new encodings of old instructions) (note: the instructions with 'W' at the end of their name are 32-bit versions of the instructions, since the un-suffixed instructions inherited from RV32I change to 64-bit in RV64I; the way i think about this is that un-suffixed instructions operate with whatever bitwidth the registers are, which is 32-bits in RV32I and 64-bits in RV64I, unless they are specifically made to operate on a certain bitwidth, in which case this is indicated with a suffix to the instruction name):
- add, subtract: addw addiw subw
- shifts: sllw slliw srlw srliw sraw sraiw
- loads and stores: ld sd lwu
- (there are also new encodings of SLLI SRLI SRAI)
RV32M (multiply extension; 8 instructions):
- mul mulh mulhu mulhsu div divu rem remu
RV64M (multiply extension; 13 instructions) (note: RV64M includes everything in RV32M, but adapted for 64-bit, plus these) (5 new instructions):
- mulw divw divuw remw remuw
RV32A (32-bit atomics extension; 11 instructions):
- lr.w sc.w amoswap.w amoadd.w amoxor.w amoand.w amoor.w amomin.w amomax.w amominu.w amomaxu.w
RV64A (64-bit atomics extension; 22 instructions) (note: RV64A includes everything in RV32A, plus these) (11 new instructions):
- new instructions with names the same as RV32A instruction names but with .d suffixes instead of .w, and with similiar functionality but 64-bit
RV32F (32-bit/single-precision floating point extension for RV32I: 26 instructions):
- Add, subtract, multiply, divide: fadd.s fsub.s fmul.s fdiv.s
- compares: feq.s flt.s fle.s
- floating-point specific:
- sqrt: fsqrt.s
- fused multiply-add: fmadd.s fmsub.s fnmadd.s fnmsub.s
- signs: fsgnj.s fsgnjn.s fsgnjx.s
- min, max: fmin.s fmax.s
- classify: fclass.s
- rounding: (pseudoinstructions: frrm fsrm fsrmi)
- exceptions: (pseudoinstructions: frflags fsflags fsflagsi)
- misc fp: (pseudoinstructions: frcsr fscsr)
- conversions:
- fmv.w.x fmv.x.w
- fcvt.s.w fcvt.s.wu fcvt.w.s fcvt.wu.s
- loads and stores: flw fsw
RV64F (32-bit/single-precision floating point extension for RV64I: 30 instructions) (note: RV64F includes everything in RV32F, plus these) (4 new instructions):
- conversions: fcvt.s.l fcvt.s.lu fcvt.l.s fcvt.lu.s
RV32D (64-bit/double-precision floating point extension for RV64I: 26 instructions):
- new instructions with names the same as most of the RV32F instruction names but with .d suffixes instead of .s, and with similiar functionality but 64-bit; EXCEPT:
- there are no new fmv* instructions here (because the 64-bit double-precision floating point won't fit in 32-bit integer registers)
- there are two new instructions for converting between 32-bit/single-precision floating point and 64-bit/double-precision floating point: fcvt.s.d fcvt.d.s
RV64D (64-bit/double-precision floating point extension for RV64I: 32 instructions) (note: RV64D includes everything in RC32D, plus these) (6 new instructions):
- fmv.c.d fmv.d.x fcvt.d.l fcvt.d.lu fcvt.l.d fcvt.lu.d
(so, RV64IMAFD, otherwise known as RV64G, contains 156 instructions in total)
WASM instruction list (172 instructions)
control:
- branches: br br_if br_table
- subroutines: return call call_indirect
- other structured control: block loop if else end
- control misc: unreachable nop
parametric:
constant loads:
- i32.const i64.const f32.const f64.const
loads and stores:
- loads: i32.load i64.load f32.load f64.load i32.load8_s i32.load8_u i32.load16_s i32.load16_u i64.load8_s i64.load8_u i64.load16_s i64.load16_u i64.load32_s i64.load32_u
- stores: i32.store i64.store f32.store f64.store i32.store8 i32.store16 i64.store8 i64.store16 i64.store32
- variables: local.get local.set local.tee global.get global.set
comparisons:
- integer comparisons: i32.eqz i32.eq i32.ne i32.lt_s i32.lt_u i32.le_s i32.le_u i32.gt_s i32.gt_u i32.ge_s i32.ge_u, and corresponding instructions for i64
- floating point comparisons: f32.eq f32.ne f32.lt f32.le f32.gt f32.ge, and corresponding instructions for f64
arithmetic:
- add, subtract, multiply, divide:
- i32.add i32.sub i32.mul i32.div_s i32.div_u i32.rem_s i32.rem_u, and corresponding instructions for i64
- f32.add f32.sub f32.mul f32.div, and corresponding instructions for f64
- logical: i32.and i32.or i32.xor, and corresponding instructions for each i64
- shifts: i32.shl i32.shr_s i32.shr_u i32.rotl i32.rotr, and corresponding instructions for i64
- misc bitwise arithmetic: i32.clz i32.ctz i32.popcnt, and corresponding instructions for i64
- floating-point specific: f32.abs f32.neg f32.ceil f32.floor f32.trunc f32.nearest f32.sqrt f32.min f32.max f32.copysign, and corresponding instructions for f64
conversions:
- f{32,64}.convert_i{32,64}_{s,u}, i{32,64}.trunc_f{32,64}_{s,u}
- i32.reinterpret_f32 i64.reinterpret_f64 f32.reinterpret_i32 f64.reinterpret_i64
- i32.wrap_i64 i64.extend_i32_s i64.extend_i32_u
- f32.demote_f64 f64.promote_f32
allocation: memory.size memory.grow
LLVM instruction list
LLVM instructions (64 instructions):
- Terminator Instructions: ret br switch indirectbr invoke callbr resume catchswitch catchret cleanupret unreachable
- Unary Operations: fneg
- Binary Operations: add fadd sub fsub mul fmul udiv sdiv fdiv urem srem frem
- Bitwise Binary Operations: shl lshr ashr and or xor
- Vector Operations: extractelement insertelement shufflevector
- Aggregate Operations: extractvalue insertvalue
- Memory Access and Addressing Operations: alloca load store fence cmpxchg atomicrmw getelementptr
- Conversion Operations: trunc zext sext fptrunc fpext fptoui fptosi uitofp sitofp ptrtoint inttoptr bitcast addrspacecast
- Other: icmp fcmp phi select call va_arg landingpad catchpad cleanuppad
LLVM intrinsics (185 intrinsics, if the families denoted by the '*'s below are each grouped together and counted as one):
- Variable Argument Handling Intrinsics: va_start va_end va_copy
- Accurate Garbage Collection Intrinsics: gcroot gcread gcwrite llvm.experimental.gc.statepoint llvm.experimental.gc.result llvm.experimental.gc.relocate
- Code Generator Intrinsics: returnaddress addressofreturnaddress sponentry frameaddress localescape localrecover read_register write_register stacksave stackrestore get.dynamic.area.offset prefetch pcmarker readcyclecounter clear_cache instrprof.increment instrprof.increment.step instrprof.value.profile thread.pointer
- Standard C Library Intrinsics: memcpy memmove memset.* sqrt.* powi.* sin.* cos.* pow.* exp.* exp2.* log.* log10.* log2.* fma.* fabs.* minnum.* maxnum.* minimum.* maximum.* copysign.* floor.* ceil.* trunc.* rint.* nearbyint.* round.*
- Bit Manipulation Intrinsics: bitreverse.* bswap.* ctpop.* ctlz.* cttz.* fshl.* fshr.*
- Arithmetic with Overflow Intrinsics: sadd.with.overflow.* uadd.with.overflow.* ssub.with.overflow.* usub.with.overflow.* smul.with.overflow.* umul.with.overflow.*
- Saturation Arithmetic Intrinsics: sadd.sat.* uadd.sat.* ssub.sat.* usub.sat.*
- Fixed Point Arithmetic Intrinsics: smul.fix.* umul.fix.*
- Specialised Arithmetic Intrinsics: canonicalize.* fmuladd.*
- Experimental Vector Reduction Intrinsics: experimental.vector.reduce.add.* experimental.vector.reduce.fadd.* experimental.vector.reduce.mul.* experimental.vector.reduce.fmul.* experimental.vector.reduce.and.* experimental.vector.reduce.or.* experimental.vector.reduce.xor.* experimental.vector.reduce.smax.* experimental.vector.reduce.smin.* experimental.vector.reduce.umax.* experimental.vector.reduce.umin.* experimental.vector.reduce.fmax.* experimental.vector.reduce.fmin.*
- Half Precision Floating-Point Intrinsics: convert.to.fp16 convert.from.fp16
- Debugger Intrinsics: llvm.dbg.addr llvm.dbg.declare llvm.dbg.value
- Exception Handling Intrinsics: llvm.eh.typeid.for llvm.eh.begincatch llvm.eh.endcatch llvm.eh.exceptionpointer llvm.eh.sjlj.setjmp llvm.eh.sjlj.longjmp llvm.eh.sjlj.lsda llvm.eh.sjlj.callsite
- Trampoline Intrinsics: init.trampoline adjust.trampoline
- Masked Vector Load and Store Intrinsics: masked.load.* masked.store.*
- Masked Vector Gather and Scatter Intrinsics: masked.gather.* masked.scatter.*
- Masked Vector Expanding Load and Compressing Store Intrinsics: masked.expandload.* masked.compressstore.*
- Memory Use Markers: lifetime.start lifetime.end invariant.start invariant.end launder.invariant.group strip.invariant.group
- Constrained Floating-Point Intrinsics: experimental.constrained.fadd experimental.constrained.fsub experimental.constrained.fmul experimental.constrained.fdiv experimental.constrained.frem experimental.constrained.fma experimental.constrained.fptrunc experimental.constrained.fpext
- Constrained libm-equivalent Intrinsics: experimental.constrained.sqrt experimental.constrained.pow experimental.constrained.powi experimental.constrained.sin experimental.constrained.cos experimental.constrained.exp experimental.constrained.exp2 experimental.constrained.log experimental.constrained.log10 experimental.constrained.log2 experimental.constrained.rint experimental.constrained.nearbyint experimental.constrained.maxnum experimental.constrained.minnum experimental.constrained.ceil experimental.constrained.floor experimental.constrained.round experimental.constrained.trunc
- General Intrinsics: var.annotation ptr.annotation.* annotation.* codeview.annotation trap debugtrap stackprotector stackguard objectsize expect assume ssa_copy type.test type.checked.load donothing experimental.deoptimize experimental.guard experimental.widenable.condition load.relative sideeffect is.constant.*
- Stack Map Intrinsics: llvm.experimental.stackmap llvm.experimental.patchpoint.*
- Element Wise Atomic Memory Intrinsics: memcpy.element.unordered.atomic memmove.element.unordered.atomic memset.element.unordered.atomic
- Objective-C ARC Runtime Intrinsics: objc.autorelease objc.autoreleasePoolPop objc.autoreleasePoolPush objc.autoreleaseReturnValue objc.copyWeak objc.destroyWeak objc.initWeak objc.loadWeak objc.loadWeakRetained objc.moveWeak objc.release objc.retain objc.retainAutorelease objc.retainAutoreleaseReturnValue objc.retainAutoreleasedReturnValue objc.retainBlock objc.storeStrong objc.storeWeak
ARM Cortex M0 instruction list (59 instructions)
- Moves: mov movs
- add, subtract, multiply: add adds adcs adr sub subs sbcs rsbs muls
- compare: cmp cmn
- logical: ands eors orrs bics mvns tst
- shift: lsls lsrs asrs
- rotate: rors
- load, store: ldr ldrh ldrb ldrsh ldrsb ldm str strh strb stm
- push, pop: push pop
- branch: b bx blx
- branch (32-bit Thumb instruction): bl
- extend: sxth sxtb uxth uxtb
- reverse: rev rev16 revsh
- state change: svc cpsid cpsie bkpt
- state change: mrs msr (32-bit Thumb instructions)
- hint: sev wfe wfi nop
- barriers (32-bit Thumb instructions): isb dmb dsb
All instructions are 16-bit Thumb (Thumb-1) instructions except for the 32-bit Thumb instructions (Thumb-2) indicated.
These instructions are: "all of the 16-bit Thumb instructions from ARMv7-M excluding CBZ, CBNZ and IT" plus "the 32-bit Thumb instructions BL, DMB, DSB, ISB, MRS and MSR" [1].
Note: the ARM instruction mnemonics listed in [2] often have the letter 'S' at the end of them; for instance, 'ANDS' is the mnemonic for logical AND. In addition, sometimes there are two variants of an instruction, one with an 'S' and one without, for instance, MOVS and MOV. In these cases, the 'S' suffix means that the flags are updated. This 'S' suffix causes the instruction listing that we use here (from [3]) to differ slightly from (a) the instruction listing in https://en.wikipedia.org/wiki/ARM_Cortex-M#Instruction_sets and (b) the instruction names in the headings (but not the bodies) of sections within [4], both of which use mnemonics without this 'S' suffix (and combine mnemonics that differ only in the inclusion of this 'S').
Note: the set of mnemonics found at [5] is identical to that found at [6] except that the latter includes YIELD. [7] also includes YIELD. We do not include YIELD here because it is not in [8], and because [9] indicates in a footnote that it executes as NOP.
Note: as of this writing, the set of mnemonics found at [10] includes just one 'CPS' whereas the other sources have both CPSID and CPSIE. Here we include both CPSID and CPSIE.
JVM instruction list (206 instructions)
- loading constants:
- aconst_null
- bipush
- dconst_0 dconst_1
- fconst_0 fconst_1 fconst_2
- iconst_m1 iconst_0 iconst_1 iconst_2 iconst_3 iconst_4 iconst_5
- lconst_0 lconst_1
- ldc ldc_w ldc2_w
- sipush
- addition, subtraction, multiplication, division:
- dadd fadd iadd ladd
- dsub fsub isub lsub
- dmul fmul imul lmul
- ddiv fdiv idiv ldiv
- drem frem irem lrem
- dneg fneg ineg lneg
- comparisons:
- dcmpg dcmpl
- fcmpg fcmpl
- lcmp
- arrays:
- anewarray newarray multianewarray arraylength
- aaload aastore
- baload bastore
- caload castore
- daload dastore
- faload fastore
- iaload iastore
- laload lastore
- saload sastore
- OOP:
- new checkcast instanceof
- getfield getstatic putfield putstatic
- invokedynamic invokeinterface invokespecial invokestatic invokevirtual
- areturn dreturn freturn ireturn lreturn return
- variable loads/stores:
- aload aload_0 aload_1 aload_2 aload_3 astore astore_0 astore_1 astore_2 astore_3
- dload dload_0 dload_1 dload_2 dload_3 dstore dstore_0 dstore_1 dstore_2 dstore_3
- fload fload_0 fload_1 fload_2 fload_3 fstore fstore_0 fstore_1 fstore_2 fstore_3
- iload iload_0 iload_1 iload_2 iload_3 istore istore_0 istore_1 istore_2 istore_3
- lload lload_0 lload_1 lload_2 lload_3 lstore lstore_0 lstore_1 lstore_2 lstore_3
- variable indexed operations: iinc
- exception handling: athrow
- stack ops:
- dup dup_x1 dup_x2 dup2 dup2_x1 dup2_x2
- pop pop2
- swap
- conversions:
- d2f d2i d2l
- f2d f2i f2l
- i2b i2c i2d i2f i2l i2s
- l2d l2f l2i
- jumps: goto goto_w jsr jsr_w ret
- switch: lookupswitch tableswitch
- compare-and-branch:
- if_acmpeq if_acmpne if_icmpeq if_icmpge if_icmpgt if_icmple if_icmplt if_icmpne
- ifeq ifge ifgt ifle iflt ifne
- ifnonnull ifnull
- bitwise logical:
- iand ior ixor
- land lor lxor
- shifts:
- ishl ishr iushr
- lshl lshr lushr
- sync: monitorenter monitorexit
- misc: breakpoint impdep1 impdep2 nop wide
note: jsr, jsr_w, ret have effectively been deprecated; see [11]
JVM instruction list discussion:
Many of the JVM's instructions are organized around the types reference (also called address ('a'), or objectref), array, byte, char, double, float, integer, long, short.
The array type is a data structure. There are instructions to create new arrays and to get their length. For each of the, there are instructions to load items of that type from arrays and to store them into arrays.
There are a few types for which few instructions are provided that are specific to that type. These are byte, char, and short. Each of these have instructions to load and store the type from/into an array. Each of these have instructions to convert an integer into a value of the type. Byte and short have instructions to push an immediate constant of that type onto the stack.
This leaves what i'll refer to as the 'main types': reference, double, float, integer, long.
The main numerical types can be grouped into floating-point (double, float), and integral (integer, long). Out of the main numerical types, integer is the primary workhorse.
The reference type is a pointer. It has a distinguished element 'null'. This is the only type that can be thrown. Like the main numerical types, there are instructions to load references from/store them to variables, and return them from methods. There are compare-and-branch instructions that branch based on the equality, or lack of equality, of two references, and that branch based on whether or not a reference is null.
Each of the main numerical types has instructions to push constants 0 and 1 in that type onto the stack. Floats also have an instruction to push 2, and integers also have instructions to push -1, 3, 4, and 5. Each of the main numerical types has instructions for addition, subtraction, multiplication, division, remainder. Except for integers, they each have compare instructions, which push a bool or integer to indicate the result of the comparison (presumably integers don't need this because presumably the use of these comparison results is as inputs to compare-and-branch instructions, which take integer arguments directly). The floating-point (double and float) types have two variants of these compare instructions with different behavior only on NaNs?. Each of the main numerical types has instructions to load from/store to local variables. Each of the main numerical types has instructions to convert to each of the other main numerical types, and integers also can be converted to bytes, chars, and shorts. The integral types has bitwise logical and bitshift operators.
Integers have compare-and-branch instructions that branch based on the inequality of two integers; ==, !=, <=, <, >, >=. There are also compare-and-branch instructions that branch based on the inequality of one integer and zero (again, ==, !=, <=, <, >, >=). There is an increment operator that operates directly on integer variables.
There are instructions for loading constants from the constant table. There are a number of polymorphic stack instructions; various 'dup's, pops, and swap. Instructions for control flow include jumps and switches. There are many OOP instructions for working with objects, and for invoking and returning from methods. Finally, there are also synchronization and miscellaneous operations.
LuaJIT2 instruction list (94 instructions)
Comparison: islt isge isle isgt iseqv isnev iseqs isnes iseqn isnen iseqp isnep Unary Test and Copy: istc isfc ist isf Unary: mov not unm len binary: addvn subvn mulvn divvn modvn addnv subnt mulnv divnv modnv addvv subvv mulvv divvv modvv pow cat constant: kstr kdata kshort knum kpri knil Upvalue and Function: uget usetv usets usetn usetp uclo fnew table: tnew tdup gget gset tgetv tgets tgetb tsetv tsets tsetb tsetm Calls and Vararg Handling: callm call callmt callt iterc itern varg isnext Returns: retm ret ret0 ret1 Loops and branches: fori jfori forl iforl jforl iterl iiterl jiterl loop iloop jloop jmp Function headers: funcf ifuncf jfuncf funcv ifuncv jfuncv funcc funccw func
Discussion:
As an optimized instruction set, LuaJIT?2 includes various 'immediate' instructions, such as TGETB and TSETB, which index into a table data structure with an 8-bit immediate constant integer index.
The LuaJIT?2 instruction set is based upon the Lua instruction set, version 5.1 of which is documented at http://luaforge.net/docman/83/98/ANoFrillsIntroToLua51VMInstructions.pdf .
CIL instruction list (229 instructions)
addition, subtraction, multiplication, division:
- add add.ovf add.ovf.un div div.un mul mul.ovf mul.ovf.un neg rem rem.un sub sub.ovf sub.ovf.un
logical:
function calling:
- calls: call calli callvirt
- argument handling: arglist ldarg ldarg.0 ldarg.1 ldarg.2 ldarg.3 ldarg.s ldarga ldarga.s starg starg.s
- returns: ret
- tailcall: tail.
conditional branches:
- beq beq.s bge bge.s bge.un bge.un.s bgt bgt.s bgt.un bgt.un.s ble ble.s ble.un ble.un.s blt blt.s blt.un blt.un.s bne.un bne.un.s brfalse brfalse.s brinst brinst.s brnull brnull.s brtrue brtrue.s brzero brzero.s
misc:
- break no.typecheck/rangecheck/nullcheck nop readonly. unaligned. volatile.
oop:
- box castclass constrained cpobj initobj isinst ldfld ldflda ldftn ldobj ldsfld ldsflda ldstr ldtoken ldvirtftn mkrefany newobj refanytype refanyval sizeof stfld stobj stsfld unbox unbox.any
arrays:
- ldelem ldelem.i ldelem.i1 ldelem.i2 ldelem.i4 ldelem.i8 ldelem.r4 ldelem.r8 ldelem.ref ldelem.u1 ldelem.u2 ldelem.u4 ldelem.u8 ldelema ldlen newarr stelem stelem.i stelem.i1 stelem.i2 stelem.i4 stelem.i8 stelem.r4 stelem.r8 stelem.ref
jump:
comparisons:
- ceq cgt cgt.un clt clt.un
floating-point specific:
conversions:
- conv.i conv.i1 conv.i2 conv.i4 conv.i8 conv.ovf.i conv.ovf.i.un conv.ovf.i1 conv.ovf.i1.un conv.ovf.i2 conv.ovf.i2.un conv.ovf.i4 conv.ovf.i4.un conv.ovf.i8 conv.ovf.i8.un conv.ovf.u conv.ovf.u.un conv.ovf.u1 conv.ovf.u1.un conv.ovf.u2 conv.ovf.u2.un conv.ovf.u4 conv.ovf.u4.un conv.ovf.u8 conv.ovf.u8.un conv.r.un conv.r4 conv.r8 conv.u conv.u1 conv.u2 conv.u4 conv.u8
misc memory ops:
stack ops:
exception handling:
- endfault endfilter endfinally leave leave.s rethrow throw
constant loads:
- ldc.i4 ldc.i4.0 ldc.i4.1 ldc.i4.2 ldc.i4.3 ldc.i4.4 ldc.i4.5 ldc.i4.6 ldc.i4.7 ldc.i4.8 ldc.i4.m1 ldc.i4.M1 ldc.i4.s ldc.i8 ldc.r4 ldc.r8 ldnull
loads and stores:
- loads: ldind.i ldind.i1 ldind.i2 ldind.i4 ldind.i8 ldind.r4 ldind.r8 ldind.ref ldind.u1 ldind.u2 ldind.u4 ldind.u8
- stores: stind.i stind.i1 stind.i2 stind.i4 stind.i8 stind.r4 stind.r8 stind.ref
- variables: ldloc ldloc.0 ldloc.1 ldloc.2 ldloc.3 ldloc.s ldloca ldloca.s stloc stloc.0 stloc.1 stloc.2 stloc.3 stloc.s
allocation:
shifts:
Misc tables
List of conditionals by type, including both compares and compare-and-branches
In most of the previous sections, we separated comparison operations (with no control flow) from conditional compare-and-branch operations. Since some platforms have a greater variety of compare instructions and fewer compare-and-branch instructions, and others have fewer compare instructions and a greater variety of compare-and-branch instructions, this makes it more difficult to see the popularity of different comparison relations.
So, in this section we group instructions by which relation they test, regardless of whether they are comparison operations or compare-and-branch operations.
For each grouping, we give a count of the platforms which offer an instruction in that group. Since ARM doesn't have floating-point instructions and LuaJIT?2 doesn't have integer instructions, these counts are never more than 6. If the count is 5, we indicate which platforms are missing (which will always be one of ARM, LuaJIT?2, and then one other platform).
Equality
Equals
integer equals (6):
- branch int: BEQ (Branch =) (i32) (RISC-V RV32I)
- compare int: i32.eq i64.eq (WASM)
- compare int: icmp eq (LLVM)
- branch int: beq (ARM)
- branch int: if_acmpeq if_icmpeq (JVM)
- branch int: beq beq.s (polymorphic) (CIL)
- compare int: ceq (polymorphic) (CIL)
float equals (6):
- compare float: FEQ.S, FEQ.D (f32, f64) (RISC-V F): dest = (f32 == f32)
- compare float: f32.eq, f64.eq (WASM)
- compare float: fcmp eq and ordered (LLVM)
- compare float: fcmp eq or unordered (LLVM)
- compare float: trinary: dcmpg dcmpl fcmpg fcmpl (JVM)
- branch float: iseqv iseqn (LuaJIT?2)
- branch float: beq beq.s (CIL)
- compare float: ceq (polymorphic) (CIL)
note: RISC-V, JVM's branches don't work on floats. LuaJIT?'s branches are only on floats (and pris and strings)
Not-equals
integer not-equals (6):
- branch int: BNE (Branch !=) (i32) (RISC-V RV32I)
- cmp int: i32.ne i64.ne (WASM)
- cmp int: icmp ne (LLVM)
- branch int: bne (ARM)
- branch int: if_acmpne if_icmpne (JVM)
- branch int: bne.un bne.un.s (CIL)
float not-equals (5) (missing RISC-V, ARM):
- cmp float: f32.ne f64.ne (WASM)
- cmp float: fcmp neq and ordered, fcmp neq or unordered (LLVM)
- compare float: trinary: dcmpg dcmpl fcmpg fcmpl (JVM)
- branch float: isnev (LuaJIT?2)
- branch float: isnes isnen isnep (LuaJIT?2)
- branch float: bne.un bne.un.s (CIL)
Comparison Inequalities
Less-than
integer less-than (6):
- branch: BLT (Branch <) (i32) (RISC-V RV32I)
- compare: SLT (Set <) (i32) (RISC-V RV32I)
- compare: SLTI (Set < Immediate) (i32) (RISC-V RV32I)
- compare: i32_lt_s, i64_lt_s (WASM)
- compare: icmp slt (LLVM)
- branch: blt (ARM)
- branch: if_icmplt (JVM)
- branch: blt blt.s (CIL)
- compare: clt (CIL)
float less-than (6):
- compare: FLT.S, FLT.D (f32, f64) (RISC-V F): dest = (f32 < f32)
- compare: f32.lt, f64.lt (WASM)
- compare: fcmp lt and ordered (LLVM)
- compare: fcmp lt or unordered (LLVM)
- compare: trinary: dcmpg dcmpl fcmpg fcmpl (JVM)
- branch: islt (LuaJIT?2)
- branch: blt blt.s (CIL)
- compare: clt (CIL)
unsigned integer less-than (5) (missing JVM, LuaJIT?