Skip to content

Instantly share code, notes, and snippets.

@agustingianni
Created May 7, 2017 19:15
Show Gist options
  • Select an option

  • Save agustingianni/2d78a1607afcefed06c77748b9c371ee to your computer and use it in GitHub Desktop.

Select an option

Save agustingianni/2d78a1607afcefed06c77748b9c371ee to your computer and use it in GitHub Desktop.
This file has been truncated, but you can view the full file.
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"bits(datasize) result;",
"integer element;",
"",
"for e = 0 to elements-1",
" element = SInt(Elem[operand, e, esize]);",
" if neg then",
" element = -element;",
" else",
" element = Abs(element);",
" Elem[result, e, esize] = element; ",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 0 size#2 1 0 0 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "ABS <V><d>, <V><n>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if size != '11' then ReservedValue();",
"integer esize = 8 << UInt(size);",
"integer datasize = esize;",
"integer elements = 1;",
"boolean neg = (U == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 size#2 1 0 0 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "ABS <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if size:Q == '110' then ReservedValue();",
"integer esize = 8 << UInt(size);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"boolean neg = (U == '1');"
]
}
],
"name": "ABS",
"description": [
"Absolute value (vector)"
]
}
{
"operation": [
"bits(datasize) result;",
"bits(datasize) operand1 = X[n];",
"bits(datasize) operand2 = X[m];",
"bits(4) nzcv;",
"",
"if sub_op then",
" operand2 = NOT(operand2);",
"",
"(result, nzcv) = AddWithCarry(operand1, operand2, PSTATE.C);",
"",
"if setflags then",
" PSTATE. = nzcv;",
"",
"X[d] = result;"
],
"variants": [
{
"pattern": "sf#1 op#1 S#1 1 1 0 1 0 0 0 0 Rm#5 opcode2#6 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0",
"format": "ADC <Wd>, <Wn>, <Wm>"
},
{
"condition": "sf == 1",
"format": "ADC <Xd>, <Xn>, <Xm>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer datasize = if sf == '1' then 64 else 32;",
"boolean sub_op = (op == '1');",
"boolean setflags = (S == '1');"
]
}
],
"name": "ADC",
"description": [
"Add with Carry"
]
}
{
"operation": [
"bits(datasize) result;",
"bits(datasize) operand1 = X[n];",
"bits(datasize) operand2 = X[m];",
"bits(4) nzcv;",
"",
"if sub_op then",
" operand2 = NOT(operand2);",
"",
"(result, nzcv) = AddWithCarry(operand1, operand2, PSTATE.C);",
"",
"if setflags then ",
" PSTATE. = nzcv;",
"",
"X[d] = result;"
],
"variants": [
{
"pattern": "sf#1 op#1 S#1 1 1 0 1 0 0 0 0 Rm#5 opcode2#6 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0",
"format": "ADCS <Wd>, <Wn>, <Wm>"
},
{
"condition": "sf == 1",
"format": "ADCS <Xd>, <Xn>, <Xm>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer datasize = if sf == '1' then 64 else 32;",
"boolean sub_op = (op == '1');",
"boolean setflags = (S == '1');"
]
}
],
"name": "ADCS",
"description": [
"Add with Carry, setting flags"
]
}
{
"operation": [
"bits(datasize) result;",
"bits(datasize) operand1 = if n == 31 then SP[] else X[n];",
"bits(datasize) operand2 = ExtendReg(m, extend_type, shift);",
"bits(4) nzcv;",
"bit carry_in;",
"",
"if sub_op then",
" operand2 = NOT(operand2);",
" carry_in = '1';",
"else",
" carry_in = '0';",
"",
"(result, nzcv) = AddWithCarry(operand1, operand2, carry_in);",
"",
"if setflags then ",
" PSTATE. = nzcv;",
"",
"if d == 31 && !setflags then",
" SP[] = result;",
"else",
" X[d] = result;"
],
"variants": [
{
"pattern": "sf#1 op#1 S#1 0 1 0 1 1 opt#2 1 Rm#5 option#3 imm3#3 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0",
"format": "ADD <Wd|WSP>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}"
},
{
"condition": "sf == 1",
"format": "ADD <Xd|SP>, <Xn|SP>, <R><m>{, <extend> {#<amount>}}"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer datasize = if sf == '1' then 64 else 32;",
"boolean sub_op = (op == '1');",
"boolean setflags = (S == '1');",
"ExtendType extend_type = DecodeRegExtend(option); ",
"integer shift = UInt(imm3);",
"if shift > 4 then ReservedValue();"
]
}
],
"name": "ADD (extended register)",
"description": [
"Add (extended register)"
]
}
{
"operation": [
"bits(datasize) result;",
"bits(datasize) operand1 = if n == 31 then SP[] else X[n];",
"bits(datasize) operand2 = imm;",
"bits(4) nzcv;",
"bit carry_in;",
"",
"if sub_op then",
" operand2 = NOT(operand2);",
" carry_in = '1';",
"else",
" carry_in = '0';",
"",
"(result, nzcv) = AddWithCarry(operand1, operand2, carry_in);",
"",
"if setflags then ",
" PSTATE. = nzcv;",
"",
"if d == 31 && !setflags then",
" SP[] = result;",
"else",
" X[d] = result;"
],
"variants": [
{
"pattern": "sf#1 op#1 S#1 1 0 0 0 1 shift#2 imm12#12 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0",
"format": "ADD <Wd|WSP>, <Wn|WSP>, #<imm>{, <shift>}"
},
{
"condition": "sf == 1",
"format": "ADD <Xd|SP>, <Xn|SP>, #<imm>{, <shift>}"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer datasize = if sf == '1' then 64 else 32;",
"boolean sub_op = (op == '1');",
"boolean setflags = (S == '1');",
"bits(datasize) imm;",
"",
"case shift of",
" when '00' imm = ZeroExtend(imm12, datasize);",
" when '01' imm = ZeroExtend(imm12 : Zeros(12), datasize);",
" when '1x' ReservedValue();"
]
}
],
"name": "ADD (immediate)",
"description": [
"Add (immediate)"
]
}
{
"operation": [
"bits(datasize) result;",
"bits(datasize) operand1 = X[n];",
"bits(datasize) operand2 = ShiftReg(m, shift_type, shift_amount);",
"bits(4) nzcv;",
"bit carry_in;",
"",
"if sub_op then",
" operand2 = NOT(operand2);",
" carry_in = '1';",
"else",
" carry_in = '0';",
"",
"(result, nzcv) = AddWithCarry(operand1, operand2, carry_in);",
"",
"if setflags then ",
" PSTATE. = nzcv;",
"",
"X[d] = result;"
],
"variants": [
{
"pattern": "sf#1 op#1 S#1 0 1 0 1 1 shift#2 0 Rm#5 imm6#6 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0",
"format": "ADD <Wd>, <Wn>, <Wm>{, <shift> #<amount>}"
},
{
"condition": "sf == 1",
"format": "ADD <Xd>, <Xn>, <Xm>{, <shift> #<amount>}"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer datasize = if sf == '1' then 64 else 32;",
"boolean sub_op = (op == '1');",
"boolean setflags = (S == '1');",
"",
"if shift == '11' then ReservedValue();",
"if sf == '0' && imm6<5> == '1' then ReservedValue();",
"",
"ShiftType shift_type = DecodeShift(shift);",
"integer shift_amount = UInt(imm6);"
]
}
],
"name": "ADD (shifted register)",
"description": [
"Add (shifted register)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"bits(datasize) result;",
"bits(esize) element1;",
"bits(esize) element2;",
"",
"for e = 0 to elements-1",
" element1 = Elem[operand1, e, esize];",
" element2 = Elem[operand2, e, esize];",
" if sub_op then",
" Elem[result, e, esize] = element1 - element2;",
" else",
" Elem[result, e, esize] = element1 + element2;",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 0 size#2 1 Rm#5 opcode#5 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "ADD <V><d>, <V><n>, <V><m>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"if size != '11' then ReservedValue();",
"integer esize = 8 << UInt(size);",
"integer datasize = esize;",
"integer elements = 1;",
"boolean sub_op = (U == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 size#2 1 Rm#5 opcode#5 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "ADD <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"if size:Q == '110' then ReservedValue();",
"integer esize = 8 << UInt(size);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"boolean sub_op = (U == '1');"
]
}
],
"name": "ADD (vector)",
"description": [
"Add (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(2*datasize) operand1 = V[n];",
"bits(2*datasize) operand2 = V[m];",
"bits(datasize) result;",
"integer round_const = if round then 1 << (esize - 1) else 0;",
"bits(2*esize) element1;",
"bits(2*esize) element2;",
"bits(2*esize) sum;",
"",
"for e = 0 to elements-1",
" element1 = Elem[operand1, e, 2*esize];",
" element2 = Elem[operand2, e, 2*esize];",
" if sub_op then",
" sum = element1 - element2;",
" else",
" sum = element1 + element2;",
" sum = sum + round_const;",
" Elem[result, e, esize] = sum<2*esize-1:esize>;",
"",
"Vpart[d, part] = result;"
],
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 size#2 1 Rm#5 0 1 o1#1 0 0 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "ADDHN{2} <Vd>.<Tb>, <Vn>.<Ta>, <Vm>.<Ta>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"",
"if size == '11' then ReservedValue();",
"integer esize = 8 << UInt(size);",
"integer datasize = 64;",
"integer part = UInt(Q);",
"integer elements = datasize DIV esize;",
"",
"boolean sub_op = (o1 == '1');",
"boolean round = (U == '1');"
]
}
],
"name": "ADDHN, ADDHN2",
"description": [
"Add returning High Narrow"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"V[d] = Reduce(op, operand, esize);"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 0 size#2 1 1 0 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "ADDP <V><d>, <Vn>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if size != '11' then ReservedValue();",
"",
"integer esize = 8 << UInt(size);",
"integer datasize = esize * 2;",
"integer elements = 2;",
"",
"ReduceOp op = ReduceOp_ADD;"
]
}
],
"name": "ADDP (scalar)",
"description": [
"Add Pair of elements (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"bits(datasize) result;",
"bits(2*datasize) concat = operand2:operand1;",
"bits(esize) element1;",
"bits(esize) element2;",
"",
"for e = 0 to elements-1",
" element1 = Elem[concat, 2*e, esize];",
" element2 = Elem[concat, (2*e)+1, esize];",
" Elem[result, e, esize] = element1 + element2;",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 size#2 1 Rm#5 opcode#5 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "ADDP <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"if size:Q == '110' then ReservedValue();",
"integer esize = 8 << UInt(size);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;"
]
}
],
"name": "ADDP (vector)",
"description": [
"Add Pairwise (vector)"
]
}
{
"operation": [
"bits(datasize) result;",
"bits(datasize) operand1 = if n == 31 then SP[] else X[n];",
"bits(datasize) operand2 = ExtendReg(m, extend_type, shift);",
"bits(4) nzcv;",
"bit carry_in;",
"",
"if sub_op then",
" operand2 = NOT(operand2);",
" carry_in = '1';",
"else",
" carry_in = '0';",
"",
"(result, nzcv) = AddWithCarry(operand1, operand2, carry_in);",
"",
"if setflags then ",
" PSTATE. = nzcv;",
"",
"if d == 31 && !setflags then",
" SP[] = result;",
"else",
" X[d] = result;"
],
"variants": [
{
"pattern": "sf#1 op#1 S#1 0 1 0 1 1 opt#2 1 Rm#5 option#3 imm3#3 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0",
"format": "ADDS <Wd>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}"
},
{
"condition": "sf == 1",
"format": "ADDS <Xd>, <Xn|SP>, <R><m>{, <extend> {#<amount>}}"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer datasize = if sf == '1' then 64 else 32;",
"boolean sub_op = (op == '1');",
"boolean setflags = (S == '1');",
"ExtendType extend_type = DecodeRegExtend(option); ",
"integer shift = UInt(imm3);",
"if shift > 4 then ReservedValue();"
]
}
],
"name": "ADDS (extended register)",
"description": [
"Add (extended register), setting flags"
]
}
{
"operation": [
"bits(datasize) result;",
"bits(datasize) operand1 = if n == 31 then SP[] else X[n];",
"bits(datasize) operand2 = imm;",
"bits(4) nzcv;",
"bit carry_in;",
"",
"if sub_op then",
" operand2 = NOT(operand2);",
" carry_in = '1';",
"else",
" carry_in = '0';",
"",
"(result, nzcv) = AddWithCarry(operand1, operand2, carry_in);",
"",
"if setflags then ",
" PSTATE. = nzcv;",
"",
"if d == 31 && !setflags then",
" SP[] = result;",
"else",
" X[d] = result;"
],
"variants": [
{
"pattern": "sf#1 op#1 S#1 1 0 0 0 1 shift#2 imm12#12 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0",
"format": "ADDS <Wd>, <Wn|WSP>, #<imm>{, <shift>}"
},
{
"condition": "sf == 1",
"format": "ADDS <Xd>, <Xn|SP>, #<imm>{, <shift>}"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer datasize = if sf == '1' then 64 else 32;",
"boolean sub_op = (op == '1');",
"boolean setflags = (S == '1');",
"bits(datasize) imm;",
"",
"case shift of",
" when '00' imm = ZeroExtend(imm12, datasize);",
" when '01' imm = ZeroExtend(imm12 : Zeros(12), datasize);",
" when '1x' ReservedValue();"
]
}
],
"name": "ADDS (immediate)",
"description": [
"Add (immediate), setting flags"
]
}
{
"operation": [
"bits(datasize) result;",
"bits(datasize) operand1 = X[n];",
"bits(datasize) operand2 = ShiftReg(m, shift_type, shift_amount);",
"bits(4) nzcv;",
"bit carry_in;",
"",
"if sub_op then",
" operand2 = NOT(operand2);",
" carry_in = '1';",
"else",
" carry_in = '0';",
"",
"(result, nzcv) = AddWithCarry(operand1, operand2, carry_in);",
"",
"if setflags then ",
" PSTATE. = nzcv;",
"",
"X[d] = result;"
],
"variants": [
{
"pattern": "sf#1 op#1 S#1 0 1 0 1 1 shift#2 0 Rm#5 imm6#6 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0",
"format": "ADDS <Wd>, <Wn>, <Wm>{, <shift> #<amount>}"
},
{
"condition": "sf == 1",
"format": "ADDS <Xd>, <Xn>, <Xm>{, <shift> #<amount>}"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer datasize = if sf == '1' then 64 else 32;",
"boolean sub_op = (op == '1');",
"boolean setflags = (S == '1');",
"",
"if shift == '11' then ReservedValue();",
"if sf == '0' && imm6<5> == '1' then ReservedValue();",
"",
"ShiftType shift_type = DecodeShift(shift);",
"integer shift_amount = UInt(imm6);"
]
}
],
"name": "ADDS (shifted register)",
"description": [
"Add (shifted register), setting flags"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"V[d] = Reduce(op, operand, esize);"
],
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 size#2 1 1 0 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "ADDV <V><d>, <Vn>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if size:Q == '100' then ReservedValue();",
"if size == '11' then ReservedValue();",
"",
"integer esize = 8 << UInt(size);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"ReduceOp op = ReduceOp_ADD;"
]
}
],
"name": "ADDV",
"description": [
"Add across Vector"
]
}
{
"operation": [
"bits(64) base = PC[];",
"",
"if page then",
" base<11:0> = Zeros(12);",
"",
"X[d] = base + imm;"
],
"variants": [
{
"pattern": "op#1 immlo#2 1 0 0 0 0 immhi#19 Rd#5",
"formats": [
{
"condition": null,
"format": "ADR <Xd>, <label>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"boolean page = (op == '1');",
"bits(64) imm;",
"",
"if page then",
" imm = SignExtend(immhi:immlo:Zeros(12), 64);",
"else",
" imm = SignExtend(immhi:immlo, 64);"
]
}
],
"name": "ADR",
"description": [
"Form PC-relative address"
]
}
{
"operation": [
"bits(64) base = PC[];",
"",
"if page then",
" base<11:0> = Zeros(12);",
"",
"X[d] = base + imm;"
],
"variants": [
{
"pattern": "op#1 immlo#2 1 0 0 0 0 immhi#19 Rd#5",
"formats": [
{
"condition": null,
"format": "ADRP <Xd>, <label>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"boolean page = (op == '1');",
"bits(64) imm;",
"",
"if page then",
" imm = SignExtend(immhi:immlo:Zeros(12), 64);",
"else",
" imm = SignExtend(immhi:immlo, 64);"
]
}
],
"name": "ADRP",
"description": [
"Form PC-relative address to 4KB page"
]
}
{
"operation": [
"CheckCryptoEnabled64();",
"",
"bits(128) operand1 = V[d];",
"bits(128) operand2 = V[n];",
"bits(128) result;",
"result = operand1 EOR operand2;",
"if decrypt then",
" result = AESInvSubBytes(AESInvShiftRows(result));",
"else",
" result = AESSubBytes(AESShiftRows(result));",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 0 0 1 1 1 0 size#2 1 0 1 0 0 0 0 1 0 D#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "AESD <Vd>.16B, <Vn>.16B"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"if ! HaveCryptoExt() then UnallocatedEncoding();",
"boolean decrypt = (D == '1');"
]
}
],
"name": "AESD",
"description": [
"AES single round decryption"
]
}
{
"operation": [
"CheckCryptoEnabled64();",
"",
"bits(128) operand1 = V[d];",
"bits(128) operand2 = V[n];",
"bits(128) result;",
"result = operand1 EOR operand2;",
"if decrypt then",
" result = AESInvSubBytes(AESInvShiftRows(result));",
"else",
" result = AESSubBytes(AESShiftRows(result));",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 0 0 1 1 1 0 size#2 1 0 1 0 0 0 0 1 0 D#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "AESE <Vd>.16B, <Vn>.16B"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"if ! HaveCryptoExt() then UnallocatedEncoding();",
"boolean decrypt = (D == '1');"
]
}
],
"name": "AESE",
"description": [
"AES single round encryption"
]
}
{
"operation": [
"CheckCryptoEnabled64();",
"",
"bits(128) operand = V[n];",
"bits(128) result;",
"if decrypt then",
" result = AESInvMixColumns(operand);",
"else",
" result = AESMixColumns(operand);",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 0 0 1 1 1 0 size#2 1 0 1 0 0 0 0 1 1 D#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "AESIMC <Vd>.16B, <Vn>.16B"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"if ! HaveCryptoExt() then UnallocatedEncoding();",
"boolean decrypt = (D == '1');"
]
}
],
"name": "AESIMC",
"description": [
"AES inverse mix columns"
]
}
{
"operation": [
"CheckCryptoEnabled64();",
"",
"bits(128) operand = V[n];",
"bits(128) result;",
"if decrypt then",
" result = AESInvMixColumns(operand);",
"else",
" result = AESMixColumns(operand);",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 0 0 1 1 1 0 size#2 1 0 1 0 0 0 0 1 1 D#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "AESMC <Vd>.16B, <Vn>.16B"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"if ! HaveCryptoExt() then UnallocatedEncoding();",
"boolean decrypt = (D == '1');"
]
}
],
"name": "AESMC",
"description": [
"AES mix columns"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"bits(datasize) result;",
"",
"if invert then operand2 = NOT(operand2);",
"",
"case op of",
" when LogicalOp_AND",
" result = operand1 AND operand2;",
" when LogicalOp_ORR",
" result = operand1 OR operand2;",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 size#2 1 Rm#5 opcode#5 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "AND <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 8;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"boolean invert = (size<0> == '1');",
"LogicalOp op = if size<1> == '1' then LogicalOp_ORR else LogicalOp_AND;"
]
}
],
"name": "AND (vector)",
"description": [
"Bitwise AND (vector)"
]
}
{
"operation": [
"bits(datasize) result;",
"bits(datasize) operand1 = X[n];",
"bits(datasize) operand2 = imm;",
"",
"case op of",
" when LogicalOp_AND result = operand1 AND operand2;",
" when LogicalOp_ORR result = operand1 OR operand2;",
" when LogicalOp_EOR result = operand1 EOR operand2;",
"",
"if setflags then",
" PSTATE. = result:IsZeroBit(result):'00';",
"",
"if d == 31 && !setflags then",
" SP[] = result;",
"else",
" X[d] = result;"
],
"variants": [
{
"pattern": "sf#1 opc#2 1 0 0 1 0 0 N#1 immr#6 imms#6 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0 && N == 0",
"format": "AND <Wd|WSP>, <Wn>, #<imm>"
},
{
"condition": "sf == 1",
"format": "AND <Xd|SP>, <Xn>, #<imm>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer datasize = if sf == '1' then 64 else 32;",
"boolean setflags;",
"LogicalOp op;",
"case opc of",
" when '00' op = LogicalOp_AND; setflags = FALSE;",
" when '01' op = LogicalOp_ORR; setflags = FALSE;",
" when '10' op = LogicalOp_EOR; setflags = FALSE;",
" when '11' op = LogicalOp_AND; setflags = TRUE;",
"",
"bits(datasize) imm;",
"if sf == '0' && N != '0' then ReservedValue();",
"(imm, -) = DecodeBitMasks(N, imms, immr, TRUE);"
]
}
],
"name": "AND (immediate)",
"description": [
"Bitwise AND (immediate)"
]
}
{
"operation": [
"bits(datasize) operand1 = X[n];",
"bits(datasize) operand2 = ShiftReg(m, shift_type, shift_amount);",
"",
"if invert then operand2 = NOT(operand2);",
"",
"case op of",
" when LogicalOp_AND result = operand1 AND operand2;",
" when LogicalOp_ORR result = operand1 OR operand2;",
" when LogicalOp_EOR result = operand1 EOR operand2;",
"",
"if setflags then",
" PSTATE. = result:IsZeroBit(result):'00';",
"",
"X[d] = result;"
],
"variants": [
{
"pattern": "sf#1 opc#2 0 1 0 1 0 shift#2 N#1 Rm#5 imm6#6 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0",
"format": "AND <Wd>, <Wn>, <Wm>{, <shift> #<amount>}"
},
{
"condition": "sf == 1",
"format": "AND <Xd>, <Xn>, <Xm>{, <shift> #<amount>}"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer datasize = if sf == '1' then 64 else 32;",
"boolean setflags;",
"LogicalOp op;",
"case opc of",
" when '00' op = LogicalOp_AND; setflags = FALSE;",
" when '01' op = LogicalOp_ORR; setflags = FALSE;",
" when '10' op = LogicalOp_EOR; setflags = FALSE;",
" when '11' op = LogicalOp_AND; setflags = TRUE;",
"",
"if sf == '0' && imm6<5> == '1' then ReservedValue();",
"",
"ShiftType shift_type = DecodeShift(shift);",
"integer shift_amount = UInt(imm6);",
"boolean invert = (N == '1');"
]
}
],
"name": "AND (shifted register)",
"description": [
"Bitwise AND (shifted register)"
]
}
{
"operation": [
"bits(datasize) result;",
"bits(datasize) operand1 = X[n];",
"bits(datasize) operand2 = imm;",
"",
"case op of",
" when LogicalOp_AND result = operand1 AND operand2;",
" when LogicalOp_ORR result = operand1 OR operand2;",
" when LogicalOp_EOR result = operand1 EOR operand2;",
"",
"if setflags then",
" PSTATE. = result:IsZeroBit(result):'00';",
"",
"if d == 31 && !setflags then",
" SP[] = result;",
"else",
" X[d] = result;"
],
"variants": [
{
"pattern": "sf#1 opc#2 1 0 0 1 0 0 N#1 immr#6 imms#6 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0 && N == 0",
"format": "ANDS <Wd>, <Wn>, #<imm>"
},
{
"condition": "sf == 1",
"format": "ANDS <Xd>, <Xn>, #<imm>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer datasize = if sf == '1' then 64 else 32;",
"boolean setflags;",
"LogicalOp op;",
"case opc of",
" when '00' op = LogicalOp_AND; setflags = FALSE;",
" when '01' op = LogicalOp_ORR; setflags = FALSE;",
" when '10' op = LogicalOp_EOR; setflags = FALSE;",
" when '11' op = LogicalOp_AND; setflags = TRUE;",
"",
"bits(datasize) imm;",
"if sf == '0' && N != '0' then ReservedValue();",
"(imm, -) = DecodeBitMasks(N, imms, immr, TRUE);"
]
}
],
"name": "ANDS (immediate)",
"description": [
"Bitwise AND (immediate), setting flags"
]
}
{
"operation": [
"bits(datasize) operand1 = X[n];",
"bits(datasize) operand2 = ShiftReg(m, shift_type, shift_amount);",
"",
"if invert then operand2 = NOT(operand2);",
"",
"case op of",
" when LogicalOp_AND result = operand1 AND operand2;",
" when LogicalOp_ORR result = operand1 OR operand2;",
" when LogicalOp_EOR result = operand1 EOR operand2;",
"",
"if setflags then",
" PSTATE. = result:IsZeroBit(result):'00';",
"",
"X[d] = result;"
],
"variants": [
{
"pattern": "sf#1 opc#2 0 1 0 1 0 shift#2 N#1 Rm#5 imm6#6 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0",
"format": "ANDS <Wd>, <Wn>, <Wm>{, <shift> #<amount>}"
},
{
"condition": "sf == 1",
"format": "ANDS <Xd>, <Xn>, <Xm>{, <shift> #<amount>}"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer datasize = if sf == '1' then 64 else 32;",
"boolean setflags;",
"LogicalOp op;",
"case opc of",
" when '00' op = LogicalOp_AND; setflags = FALSE;",
" when '01' op = LogicalOp_ORR; setflags = FALSE;",
" when '10' op = LogicalOp_EOR; setflags = FALSE;",
" when '11' op = LogicalOp_AND; setflags = TRUE;",
"",
"if sf == '0' && imm6<5> == '1' then ReservedValue();",
"",
"ShiftType shift_type = DecodeShift(shift);",
"integer shift_amount = UInt(imm6);",
"boolean invert = (N == '1');"
]
}
],
"name": "ANDS (shifted register)",
"description": [
"Bitwise AND (shifted register), setting flags"
]
}
{
"operation": null,
"variants": [
{
"pattern": "sf#1 op#1 S#1 1 1 0 1 0 1 1 0 Rm#5 opcode2<5:2>#4 op2#2 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0",
"format": "ASR <Wd>, <Wn>, <Wm>"
},
{
"condition": "sf == 1",
"format": "ASR <Xd>, <Xn>, <Xm>"
}
],
"decoder": [
""
]
}
],
"name": "ASR (register)",
"description": [
"Arithmetic Shift Right (register)"
]
}
{
"operation": null,
"variants": [
{
"pattern": "sf#1 opc#2 1 0 0 1 1 0 N#1 immr#6 imms#6 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0 && N == 0 && imms == 011111",
"format": "ASR <Wd>, <Wn>, #<shift>"
},
{
"condition": "sf == 1 && N == 1 && imms == 111111",
"format": "ASR <Xd>, <Xn>, #<shift>"
}
],
"decoder": [
""
]
}
],
"name": "ASR (immediate)",
"description": [
"Arithmetic Shift Right (immediate)"
]
}
{
"operation": [
"bits(datasize) result;",
"bits(datasize) operand2 = X[m];",
"",
"result = ShiftReg(n, shift_type, UInt(operand2) MOD datasize);",
"X[d] = result;"
],
"variants": [
{
"pattern": "sf#1 op#1 S#1 1 1 0 1 0 1 1 0 Rm#5 opcode2<5:2>#4 op2#2 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0",
"format": "ASRV <Wd>, <Wn>, <Wm>"
},
{
"condition": "sf == 1",
"format": "ASRV <Xd>, <Xn>, <Xm>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer datasize = if sf == '1' then 64 else 32;",
"ShiftType shift_type = DecodeShift(op2);"
]
}
],
"name": "ASRV",
"description": [
"Arithmetic Shift Right Variable"
]
}
{
"operation": null,
"variants": [
{
"pattern": "1 1 0 1 0 1 0 1 0 0 L#1 op0#2 op1#3 CRn#4 CRm#4 op2#3 Rt#5",
"formats": [
{
"condition": null,
"format": "AT <at_op>, <Xt>"
}
],
"decoder": [
""
]
}
],
"name": "AT",
"description": [
"Address Translate"
]
}
{
"operation": [
"if ConditionHolds(condition) then",
" BranchTo(PC[] + offset, BranchType_JMP);"
],
"variants": [
{
"pattern": "0 1 0 1 0 1 0 o1#1 imm19#19 o0#1 cond#4",
"formats": [
{
"condition": null,
"format": "B.<cond> <label>"
}
],
"decoder": [
"bits(64) offset = SignExtend(imm19:'00', 64);",
"bits(4) condition = cond;"
]
}
],
"name": "B.cond",
"description": [
"Branch conditionally"
]
}
{
"operation": [
"if branch_type == BranchType_CALL then X[30] = PC[] + 4;",
"",
"BranchTo(PC[] + offset, branch_type);"
],
"variants": [
{
"pattern": "op#1 0 0 1 0 1 imm26#26",
"formats": [
{
"condition": null,
"format": "B <label>"
}
],
"decoder": [
"BranchType branch_type = if op == '1' then BranchType_CALL else BranchType_JMP;",
"bits(64) offset = SignExtend(imm26:'00', 64);"
]
}
],
"name": "B",
"description": [
"Branch"
]
}
{
"operation": null,
"variants": [
{
"pattern": "sf#1 opc#2 1 0 0 1 1 0 N#1 immr#6 imms#6 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0 && N == 0",
"format": "BFC <Wd>, #<lsb>, #<width>"
},
{
"condition": "sf == 1 && N == 1",
"format": "BFC <Xd>, #<lsb>, #<width>"
}
],
"decoder": [
""
]
}
],
"name": "BFC",
"description": [
"Bitfield Clear, leaving other bits unchanged"
]
}
{
"operation": null,
"variants": [
{
"pattern": "sf#1 opc#2 1 0 0 1 1 0 N#1 immr#6 imms#6 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0 && N == 0",
"format": "BFI <Wd>, <Wn>, #<lsb>, #<width>"
},
{
"condition": "sf == 1 && N == 1",
"format": "BFI <Xd>, <Xn>, #<lsb>, #<width>"
}
],
"decoder": [
""
]
}
],
"name": "BFI",
"description": [
"Bitfield Insert"
]
}
{
"operation": [
"bits(datasize) dst = if inzero then Zeros() else X[d];",
"bits(datasize) src = X[n];",
"",
"// perform bitfield move on low bits",
"bits(datasize) bot = (dst AND NOT(wmask)) OR (ROR(src, R) AND wmask);",
"",
"// determine extension bits (sign, zero or dest register)",
"bits(datasize) top = if extend then Replicate(src) else dst;",
"",
"// combine extension bits and result bits",
"X[d] = (top AND NOT(tmask)) OR (bot AND tmask);"
],
"variants": [
{
"pattern": "sf#1 opc#2 1 0 0 1 1 0 N#1 immr#6 imms#6 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0 && N == 0",
"format": "BFM <Wd>, <Wn>, #<immr>, #<imms>"
},
{
"condition": "sf == 1 && N == 1",
"format": "BFM <Xd>, <Xn>, #<immr>, #<imms>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer datasize = if sf == '1' then 64 else 32;",
"",
"boolean inzero;",
"boolean extend;",
"integer R;",
"integer S;",
"bits(datasize) wmask;",
"bits(datasize) tmask;",
"",
"case opc of",
" when '00' inzero = TRUE; extend = TRUE; // SBFM",
" when '01' inzero = FALSE; extend = FALSE; // BFM",
" when '10' inzero = TRUE; extend = FALSE; // UBFM",
" when '11' UnallocatedEncoding();",
"",
"if sf == '1' && N != '1' then ReservedValue();",
"if sf == '0' && (N != '0' || immr<5> != '0' || imms<5> != '0') then ReservedValue();",
"",
"R = UInt(immr);",
"S = UInt(imms);",
"(wmask, tmask) = DecodeBitMasks(N, imms, immr, FALSE);"
]
}
],
"name": "BFM",
"description": [
"Bitfield Move"
]
}
{
"operation": null,
"variants": [
{
"pattern": "sf#1 opc#2 1 0 0 1 1 0 N#1 immr#6 imms#6 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0 && N == 0",
"format": "BFXIL <Wd>, <Wn>, #<lsb>, #<width>"
},
{
"condition": "sf == 1 && N == 1",
"format": "BFXIL <Xd>, <Xn>, #<lsb>, #<width>"
}
],
"decoder": [
""
]
}
],
"name": "BFXIL",
"description": [
"Bitfield extract and insert at low end"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand;",
"bits(datasize) result;",
"",
"case operation of",
" when ImmediateOp_MOVI",
" result = imm;",
" when ImmediateOp_MVNI",
" result = NOT(imm);",
" when ImmediateOp_ORR",
" operand = V[rd];",
" result = operand OR imm;",
" when ImmediateOp_BIC",
" operand = V[rd];",
" result = operand AND NOT(imm);",
"",
"V[rd] = result;"
],
"variants": [
{
"pattern": "0 Q#1 op#1 0 1 1 1 1 0 0 0 0 0 a#1 b#1 c#1 cmode#4 o2#1 1 d#1 e#1 f#1 g#1 h#1 Rd#5",
"formats": [
{
"condition": "cmode == 10x1",
"format": "BIC <Vd>.<T>, #<imm8>{, LSL #<amount>}"
},
{
"condition": "cmode == 0xx1",
"format": "BIC <Vd>.<T>, #<imm8>{, LSL #<amount>}"
}
],
"decoder": [
"integer rd = UInt(Rd);",
"",
"integer datasize = if Q == '1' then 128 else 64;",
"bits(datasize) imm;",
"bits(64) imm64;",
"",
"ImmediateOp operation;",
"case cmode:op of",
" when '0xx00' operation = ImmediateOp_MOVI;",
" when '0xx01' operation = ImmediateOp_MVNI;",
" when '0xx10' operation = ImmediateOp_ORR;",
" when '0xx11' operation = ImmediateOp_BIC;",
" when '10x00' operation = ImmediateOp_MOVI;",
" when '10x01' operation = ImmediateOp_MVNI;",
" when '10x10' operation = ImmediateOp_ORR;",
" when '10x11' operation = ImmediateOp_BIC;",
" when '110x0' operation = ImmediateOp_MOVI;",
" when '110x1' operation = ImmediateOp_MVNI;",
" when '1110x' operation = ImmediateOp_MOVI;",
" when '11110' operation = ImmediateOp_MOVI;",
" when '11111' ",
" // FMOV Dn,#imm is in main FP instruction set",
" if Q == '0' then UnallocatedEncoding();",
" operation = ImmediateOp_MOVI;",
"",
"imm64 = AdvSIMDExpandImm(op, cmode, a:b:c:d:e:f:g:h);",
"imm = Replicate(imm64, datasize DIV 64);"
]
}
],
"name": "BIC (vector, immediate)",
"description": [
"Bitwise bit Clear (vector, immediate)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"bits(datasize) result;",
"",
"if invert then operand2 = NOT(operand2);",
"",
"case op of",
" when LogicalOp_AND",
" result = operand1 AND operand2;",
" when LogicalOp_ORR",
" result = operand1 OR operand2;",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 size#2 1 Rm#5 opcode#5 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "BIC <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 8;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"boolean invert = (size<0> == '1');",
"LogicalOp op = if size<1> == '1' then LogicalOp_ORR else LogicalOp_AND;"
]
}
],
"name": "BIC (vector, register)",
"description": [
"Bitwise bit Clear (vector, register)"
]
}
{
"operation": [
"bits(datasize) operand1 = X[n];",
"bits(datasize) operand2 = ShiftReg(m, shift_type, shift_amount);",
"",
"if invert then operand2 = NOT(operand2);",
"",
"case op of",
" when LogicalOp_AND result = operand1 AND operand2;",
" when LogicalOp_ORR result = operand1 OR operand2;",
" when LogicalOp_EOR result = operand1 EOR operand2;",
"",
"if setflags then",
" PSTATE. = result:IsZeroBit(result):'00';",
"",
"X[d] = result;"
],
"variants": [
{
"pattern": "sf#1 opc#2 0 1 0 1 0 shift#2 N#1 Rm#5 imm6#6 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0",
"format": "BIC <Wd>, <Wn>, <Wm>{, <shift> #<amount>}"
},
{
"condition": "sf == 1",
"format": "BIC <Xd>, <Xn>, <Xm>{, <shift> #<amount>}"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer datasize = if sf == '1' then 64 else 32;",
"boolean setflags;",
"LogicalOp op;",
"case opc of",
" when '00' op = LogicalOp_AND; setflags = FALSE;",
" when '01' op = LogicalOp_ORR; setflags = FALSE;",
" when '10' op = LogicalOp_EOR; setflags = FALSE;",
" when '11' op = LogicalOp_AND; setflags = TRUE;",
"",
"if sf == '0' && imm6<5> == '1' then ReservedValue();",
"",
"ShiftType shift_type = DecodeShift(shift);",
"integer shift_amount = UInt(imm6);",
"boolean invert = (N == '1');"
]
}
],
"name": "BIC (shifted register)",
"description": [
"Bitwise Bit Clear (shifted register)"
]
}
{
"operation": [
"bits(datasize) operand1 = X[n];",
"bits(datasize) operand2 = ShiftReg(m, shift_type, shift_amount);",
"",
"if invert then operand2 = NOT(operand2);",
"",
"case op of",
" when LogicalOp_AND result = operand1 AND operand2;",
" when LogicalOp_ORR result = operand1 OR operand2;",
" when LogicalOp_EOR result = operand1 EOR operand2;",
"",
"if setflags then",
" PSTATE. = result:IsZeroBit(result):'00';",
"",
"X[d] = result;"
],
"variants": [
{
"pattern": "sf#1 opc#2 0 1 0 1 0 shift#2 N#1 Rm#5 imm6#6 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0",
"format": "BICS <Wd>, <Wn>, <Wm>{, <shift> #<amount>}"
},
{
"condition": "sf == 1",
"format": "BICS <Xd>, <Xn>, <Xm>{, <shift> #<amount>}"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer datasize = if sf == '1' then 64 else 32;",
"boolean setflags;",
"LogicalOp op;",
"case opc of",
" when '00' op = LogicalOp_AND; setflags = FALSE;",
" when '01' op = LogicalOp_ORR; setflags = FALSE;",
" when '10' op = LogicalOp_EOR; setflags = FALSE;",
" when '11' op = LogicalOp_AND; setflags = TRUE;",
"",
"if sf == '0' && imm6<5> == '1' then ReservedValue();",
"",
"ShiftType shift_type = DecodeShift(shift);",
"integer shift_amount = UInt(imm6);",
"boolean invert = (N == '1');"
]
}
],
"name": "BICS (shifted register)",
"description": [
"Bitwise Bit Clear (shifted register), setting flags"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand1;",
"bits(datasize) operand2;",
"bits(datasize) operand3;",
"bits(datasize) operand4 = V[n];",
"",
"case op of",
" when VBitOp_VEOR",
" operand1 = V[m];",
" operand2 = Zeros();",
" operand3 = Ones();",
" when VBitOp_VBSL",
" operand1 = V[m];",
" operand2 = operand1;",
" operand3 = V[d];",
" when VBitOp_VBIT",
" operand1 = V[d];",
" operand2 = operand1;",
" operand3 = V[m];",
" when VBitOp_VBIF",
" operand1 = V[d];",
" operand2 = operand1;",
" operand3 = NOT(V[m]);",
"",
"V[d] = operand1 EOR ((operand2 EOR operand4) AND operand3);"
],
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 opc2#2 1 Rm#5 opcode#5 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "BIF <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 8;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"VBitOp op;",
"",
"case opc2 of",
" when '00' op = VBitOp_VEOR;",
" when '01' op = VBitOp_VBSL;",
" when '10' op = VBitOp_VBIT;",
" when '11' op = VBitOp_VBIF;"
]
}
],
"name": "BIF",
"description": [
"Bitwise Insert if False"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand1;",
"bits(datasize) operand2;",
"bits(datasize) operand3;",
"bits(datasize) operand4 = V[n];",
"",
"case op of",
" when VBitOp_VEOR",
" operand1 = V[m];",
" operand2 = Zeros();",
" operand3 = Ones();",
" when VBitOp_VBSL",
" operand1 = V[m];",
" operand2 = operand1;",
" operand3 = V[d];",
" when VBitOp_VBIT",
" operand1 = V[d];",
" operand2 = operand1;",
" operand3 = V[m];",
" when VBitOp_VBIF",
" operand1 = V[d];",
" operand2 = operand1;",
" operand3 = NOT(V[m]);",
"",
"V[d] = operand1 EOR ((operand2 EOR operand4) AND operand3);"
],
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 opc2#2 1 Rm#5 opcode#5 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "BIT <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 8;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"VBitOp op;",
"",
"case opc2 of",
" when '00' op = VBitOp_VEOR;",
" when '01' op = VBitOp_VBSL;",
" when '10' op = VBitOp_VBIT;",
" when '11' op = VBitOp_VBIF;"
]
}
],
"name": "BIT",
"description": [
"Bitwise Insert if True"
]
}
{
"operation": [
"if branch_type == BranchType_CALL then X[30] = PC[] + 4;",
"",
"BranchTo(PC[] + offset, branch_type);"
],
"variants": [
{
"pattern": "op#1 0 0 1 0 1 imm26#26",
"formats": [
{
"condition": null,
"format": "BL <label>"
}
],
"decoder": [
"BranchType branch_type = if op == '1' then BranchType_CALL else BranchType_JMP;",
"bits(64) offset = SignExtend(imm26:'00', 64);"
]
}
],
"name": "BL",
"description": [
"Branch with Link"
]
}
{
"operation": [
"bits(64) target = X[n];",
"",
"if branch_type == BranchType_CALL then X[30] = PC[] + 4;",
"BranchTo(target, branch_type);"
],
"variants": [
{
"pattern": "1 1 0 1 0 1 1 opc[3:2]#2 op#2 op2#5 op3#6 Rn#5 op4#5",
"formats": [
{
"condition": null,
"format": "BLR <Xn>"
}
],
"decoder": [
"integer n = UInt(Rn);",
"BranchType branch_type;",
"",
"case op of",
" when '00' branch_type = BranchType_JMP;",
" when '01' branch_type = BranchType_CALL;",
" when '10' branch_type = BranchType_RET;",
" otherwise UnallocatedEncoding();"
]
}
],
"name": "BLR",
"description": [
"Branch with Link to Register"
]
}
{
"operation": [
"bits(64) target = X[n];",
"",
"if branch_type == BranchType_CALL then X[30] = PC[] + 4;",
"BranchTo(target, branch_type);"
],
"variants": [
{
"pattern": "1 1 0 1 0 1 1 opc[3:2]#2 op#2 op2#5 op3#6 Rn#5 op4#5",
"formats": [
{
"condition": null,
"format": "BR <Xn>"
}
],
"decoder": [
"integer n = UInt(Rn);",
"BranchType branch_type;",
"",
"case op of",
" when '00' branch_type = BranchType_JMP;",
" when '01' branch_type = BranchType_CALL;",
" when '10' branch_type = BranchType_RET;",
" otherwise UnallocatedEncoding();"
]
}
],
"name": "BR",
"description": [
"Branch to Register"
]
}
{
"operation": [
"AArch64.SoftwareBreakpoint(comment);"
],
"variants": [
{
"pattern": "1 1 0 1 0 1 0 0 opc#3 imm16#16 op2#3 LL#2",
"formats": [
{
"condition": null,
"format": "BRK #<imm>"
}
],
"decoder": [
"bits(16) comment = imm16;"
]
}
],
"name": "BRK",
"description": [
"Breakpoint instruction"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand1;",
"bits(datasize) operand2;",
"bits(datasize) operand3;",
"bits(datasize) operand4 = V[n];",
"",
"case op of",
" when VBitOp_VEOR",
" operand1 = V[m];",
" operand2 = Zeros();",
" operand3 = Ones();",
" when VBitOp_VBSL",
" operand1 = V[m];",
" operand2 = operand1;",
" operand3 = V[d];",
" when VBitOp_VBIT",
" operand1 = V[d];",
" operand2 = operand1;",
" operand3 = V[m];",
" when VBitOp_VBIF",
" operand1 = V[d];",
" operand2 = operand1;",
" operand3 = NOT(V[m]);",
"",
"V[d] = operand1 EOR ((operand2 EOR operand4) AND operand3);"
],
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 opc2#2 1 Rm#5 opcode#5 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "BSL <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 8;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"VBitOp op;",
"",
"case opc2 of",
" when '00' op = VBitOp_VEOR;",
" when '01' op = VBitOp_VBSL;",
" when '10' op = VBitOp_VBIT;",
" when '11' op = VBitOp_VBIF;"
]
}
],
"name": "BSL",
"description": [
"Bitwise Select"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) comparevalue;",
"bits(datasize) newvalue;",
"bits(datasize) data;",
"",
"comparevalue = X[s];",
"newvalue = X[t];",
"if n == 31 then ",
" CheckSPAlignment(); ",
" address = SP[];",
"else ",
" address = X[n];",
"data = Mem[address, datasize DIV 8, ldacctype];",
"if data == comparevalue then ",
" // All observers in the shareability domain observe the",
" // following load and store atomically.",
" Mem[address, datasize DIV 8, stacctype] = newvalue;",
"",
"X[s] = ZeroExtend(data, regsize);"
],
"variants": [
{
"pattern": "size#2 0 0 1 0 0 0 o2#1 L#1 o1#1 Rs#5 o0#1 Rt2#5 Rn#5 Rt#5",
"formats": [
{
"condition": "size == 10 && L == 1 && o0 == 0",
"format": "CASA <Ws>, <Wt>, [<Xn|SP>{,#0}]"
},
{
"condition": "size == 10 && L == 1 && o0 == 1",
"format": "CASAL <Ws>, <Wt>, [<Xn|SP>{,#0}]"
},
{
"condition": "size == 10 && L == 0 && o0 == 0",
"format": "CAS <Ws>, <Wt>, [<Xn|SP>{,#0}]"
},
{
"condition": "size == 10 && L == 0 && o0 == 1",
"format": "CASL <Ws>, <Wt>, [<Xn|SP>{,#0}]"
},
{
"condition": "size == 11 && L == 1 && o0 == 0",
"format": "CASA <Xs>, <Xt>, [<Xn|SP>{,#0}]"
},
{
"condition": "size == 11 && L == 1 && o0 == 1",
"format": "CASAL <Xs>, <Xt>, [<Xn|SP>{,#0}]"
},
{
"condition": "size == 11 && L == 0 && o0 == 0",
"format": "CAS <Xs>, <Xt>, [<Xn|SP>{,#0}]"
},
{
"condition": "size == 11 && L == 0 && o0 == 1",
"format": "CASL <Xs>, <Xt>, [<Xn|SP>{,#0}]"
}
],
"decoder": [
"if !HaveAtomicExt() then UnallocatedEncoding();",
"",
"integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"integer s = UInt(Rs);",
"",
"integer datasize = 8 << UInt(size);",
"integer regsize = if datasize == 64 then 64 else 32;",
"AccType ldacctype = if L == '1' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"AccType stacctype = if o0 == '1' then AccType_ORDEREDRW else AccType_ATOMICRW;"
]
}
],
"name": "CAS, CASA, CASAL, CASL",
"description": [
"Compare and Swap word or doubleword in memory"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) comparevalue;",
"bits(datasize) newvalue;",
"bits(datasize) data;",
"",
"comparevalue = X[s];",
"newvalue = X[t];",
"if n == 31 then ",
" CheckSPAlignment(); ",
" address = SP[];",
"else ",
" address = X[n];",
"data = Mem[address, datasize DIV 8, ldacctype];",
"if data == comparevalue then ",
" // All observers in the shareability domain observe the",
" // following load and store atomically.",
" Mem[address, datasize DIV 8, stacctype] = newvalue;",
"",
"X[s] = ZeroExtend(data, regsize);"
],
"variants": [
{
"pattern": "size#2 0 0 1 0 0 0 o2#1 L#1 o1#1 Rs#5 o0#1 Rt2#5 Rn#5 Rt#5",
"formats": [
{
"condition": "L == 1 && o0 == 0",
"format": "CASAB <Ws>, <Wt>, [<Xn|SP>{,#0}]"
},
{
"condition": "L == 1 && o0 == 1",
"format": "CASALB <Ws>, <Wt>, [<Xn|SP>{,#0}]"
},
{
"condition": "L == 0 && o0 == 0",
"format": "CASB <Ws>, <Wt>, [<Xn|SP>{,#0}]"
},
{
"condition": "L == 0 && o0 == 1",
"format": "CASLB <Ws>, <Wt>, [<Xn|SP>{,#0}]"
}
],
"decoder": [
"if !HaveAtomicExt() then UnallocatedEncoding();",
"",
"integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"integer s = UInt(Rs);",
"",
"integer datasize = 8 << UInt(size);",
"integer regsize = if datasize == 64 then 64 else 32;",
"AccType ldacctype = if L == '1' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"AccType stacctype = if o0 == '1' then AccType_ORDEREDRW else AccType_ATOMICRW;"
]
}
],
"name": "CASB, CASAB, CASALB, CASLB",
"description": [
"Compare and Swap byte in memory"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) comparevalue;",
"bits(datasize) newvalue;",
"bits(datasize) data;",
"",
"comparevalue = X[s];",
"newvalue = X[t];",
"if n == 31 then ",
" CheckSPAlignment(); ",
" address = SP[];",
"else ",
" address = X[n];",
"data = Mem[address, datasize DIV 8, ldacctype];",
"if data == comparevalue then ",
" // All observers in the shareability domain observe the",
" // following load and store atomically.",
" Mem[address, datasize DIV 8, stacctype] = newvalue;",
"",
"X[s] = ZeroExtend(data, regsize);"
],
"variants": [
{
"pattern": "size#2 0 0 1 0 0 0 o2#1 L#1 o1#1 Rs#5 o0#1 Rt2#5 Rn#5 Rt#5",
"formats": [
{
"condition": "L == 1 && o0 == 0",
"format": "CASAH <Ws>, <Wt>, [<Xn|SP>{,#0}]"
},
{
"condition": "L == 1 && o0 == 1",
"format": "CASALH <Ws>, <Wt>, [<Xn|SP>{,#0}]"
},
{
"condition": "L == 0 && o0 == 0",
"format": "CASH <Ws>, <Wt>, [<Xn|SP>{,#0}]"
},
{
"condition": "L == 0 && o0 == 1",
"format": "CASLH <Ws>, <Wt>, [<Xn|SP>{,#0}]"
}
],
"decoder": [
"if !HaveAtomicExt() then UnallocatedEncoding();",
"",
"integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"integer s = UInt(Rs);",
"",
"integer datasize = 8 << UInt(size);",
"integer regsize = if datasize == 64 then 64 else 32;",
"AccType ldacctype = if L == '1' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"AccType stacctype = if o0 == '1' then AccType_ORDEREDRW else AccType_ATOMICRW;"
]
}
],
"name": "CASH, CASAH, CASALH, CASLH",
"description": [
"Compare and Swap halfword in memory"
]
}
{
"operation": [
"bits(64) address;",
"bits(2*datasize) comparevalue;",
"bits(2*datasize) newvalue;",
"bits(2*datasize) data;",
"",
"bits(datasize) s1 = X[s];",
"bits(datasize) s2 = X[s+1];",
"bits(datasize) t1 = X[t];",
"bits(datasize) t2 = X[t+1];",
"comparevalue = if BigEndian() then s1:s2 else s2:s1;",
"newvalue = if BigEndian() then t1:t2 else t2:t1;",
"",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"data = Mem[address, (2 * datasize) DIV 8, ldacctype];",
"if data == comparevalue then",
" // All observers in the shareability domain observe the",
" // following load and store atomically.",
" Mem[address, (2 * datasize) DIV 8, stacctype] = newvalue;",
"",
"if BigEndian() then",
" X[s] = ZeroExtend(data<2*datasize-1:datasize>, regsize);",
" X[s+1] = ZeroExtend(data, regsize);",
"else",
" X[s] = ZeroExtend(data, regsize);",
" X[s+1] = ZeroExtend(data<2*datasize-1:datasize>, regsize);"
],
"variants": [
{
"pattern": "0 sz#1 0 0 1 0 0 0 o2#1 L#1 o1#1 Rs#5 o0#1 Rt2#5 Rn#5 Rt#5",
"formats": [
{
"condition": "sz == 0 && L == 1 && o0 == 0",
"format": "CASPA <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>{,#0}]"
},
{
"condition": "sz == 0 && L == 1 && o0 == 1",
"format": "CASPAL <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>{,#0}]"
},
{
"condition": "sz == 0 && L == 0 && o0 == 0",
"format": "CASP <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>{,#0}]"
},
{
"condition": "sz == 0 && L == 0 && o0 == 1",
"format": "CASPL <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>{,#0}]"
},
{
"condition": "sz == 1 && L == 1 && o0 == 0",
"format": "CASPA <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>{,#0}]"
},
{
"condition": "sz == 1 && L == 1 && o0 == 1",
"format": "CASPAL <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>{,#0}]"
},
{
"condition": "sz == 1 && L == 0 && o0 == 0",
"format": "CASP <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>{,#0}]"
},
{
"condition": "sz == 1 && L == 0 && o0 == 1",
"format": "CASPL <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>{,#0}]"
}
],
"decoder": [
"if !HaveAtomicExt() then UnallocatedEncoding();",
"if Rs<0> == '1' then UnallocatedEncoding();",
"if Rt<0> == '1' then UnallocatedEncoding();",
"",
"integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"integer s = UInt(Rs);",
"",
"integer datasize = 32 << UInt(sz);",
"integer regsize = datasize;",
"AccType ldacctype = if L == '1' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"AccType stacctype = if o0 == '1' then AccType_ORDEREDRW else AccType_ATOMICRW;"
]
}
],
"name": "CASP, CASPA, CASPAL, CASPL",
"description": [
"Compare and Swap Pair of words or doublewords in memory"
]
}
{
"operation": [
"bits(datasize) operand1 = X[t];",
"",
"if IsZero(operand1) == iszero then",
" BranchTo(PC[] + offset, BranchType_JMP);"
],
"variants": [
{
"pattern": "sf#1 0 1 1 0 1 0 op#1 imm19#19 Rt#5",
"formats": [
{
"condition": "sf == 0",
"format": "CBNZ <Wt>, <label>"
},
{
"condition": "sf == 1",
"format": "CBNZ <Xt>, <label>"
}
],
"decoder": [
"integer t = UInt(Rt);",
"integer datasize = if sf == '1' then 64 else 32;",
"boolean iszero = (op == '0');",
"bits(64) offset = SignExtend(imm19:'00', 64);"
]
}
],
"name": "CBNZ",
"description": [
"Compare and Branch on Nonzero"
]
}
{
"operation": [
"bits(datasize) operand1 = X[t];",
"",
"if IsZero(operand1) == iszero then",
" BranchTo(PC[] + offset, BranchType_JMP);"
],
"variants": [
{
"pattern": "sf#1 0 1 1 0 1 0 op#1 imm19#19 Rt#5",
"formats": [
{
"condition": "sf == 0",
"format": "CBZ <Wt>, <label>"
},
{
"condition": "sf == 1",
"format": "CBZ <Xt>, <label>"
}
],
"decoder": [
"integer t = UInt(Rt);",
"integer datasize = if sf == '1' then 64 else 32;",
"boolean iszero = (op == '0');",
"bits(64) offset = SignExtend(imm19:'00', 64);"
]
}
],
"name": "CBZ",
"description": [
"Compare and Branch on Zero"
]
}
{
"operation": [
"bits(datasize) operand1 = X[n];",
"bits(datasize) operand2 = imm;",
"bit carry_in = '0';",
"",
"if ConditionHolds(condition) then",
" if sub_op then",
" operand2 = NOT(operand2);",
" carry_in = '1';",
" (-, flags) = AddWithCarry(operand1, operand2, carry_in);",
"PSTATE. = flags;"
],
"variants": [
{
"pattern": "sf#1 op#1 S#1 1 1 0 1 0 0 1 0 imm5#5 cond#4 1 o2#1 Rn#5 o3#1 nzcv#4",
"formats": [
{
"condition": "sf == 0",
"format": "CCMN <Wn>, #<imm>, #<nzcv>, <cond>"
},
{
"condition": "sf == 1",
"format": "CCMN <Xn>, #<imm>, #<nzcv>, <cond>"
}
],
"decoder": [
"integer n = UInt(Rn);",
"integer datasize = if sf == '1' then 64 else 32;",
"boolean sub_op = (op == '1');",
"bits(4) condition = cond;",
"bits(4) flags = nzcv;",
"bits(datasize) imm = ZeroExtend(imm5, datasize);"
]
}
],
"name": "CCMN (immediate)",
"description": [
"Conditional Compare Negative (immediate)"
]
}
{
"operation": [
"bits(datasize) operand1 = X[n];",
"bits(datasize) operand2 = X[m];",
"bit carry_in = '0';",
"",
"if ConditionHolds(condition) then",
" if sub_op then",
" operand2 = NOT(operand2);",
" carry_in = '1';",
" (-, flags) = AddWithCarry(operand1, operand2, carry_in);",
"PSTATE. = flags;"
],
"variants": [
{
"pattern": "sf#1 op#1 S#1 1 1 0 1 0 0 1 0 Rm#5 cond#4 0 o2#1 Rn#5 o3#1 nzcv#4",
"formats": [
{
"condition": "sf == 0",
"format": "CCMN <Wn>, <Wm>, #<nzcv>, <cond>"
},
{
"condition": "sf == 1",
"format": "CCMN <Xn>, <Xm>, #<nzcv>, <cond>"
}
],
"decoder": [
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer datasize = if sf == '1' then 64 else 32;",
"boolean sub_op = (op == '1');",
"bits(4) condition = cond;",
"bits(4) flags = nzcv;"
]
}
],
"name": "CCMN (register)",
"description": [
"Conditional Compare Negative (register)"
]
}
{
"operation": [
"bits(datasize) operand1 = X[n];",
"bits(datasize) operand2 = imm;",
"bit carry_in = '0';",
"",
"if ConditionHolds(condition) then",
" if sub_op then",
" operand2 = NOT(operand2);",
" carry_in = '1';",
" (-, flags) = AddWithCarry(operand1, operand2, carry_in);",
"PSTATE. = flags;"
],
"variants": [
{
"pattern": "sf#1 op#1 S#1 1 1 0 1 0 0 1 0 imm5#5 cond#4 1 o2#1 Rn#5 o3#1 nzcv#4",
"formats": [
{
"condition": "sf == 0",
"format": "CCMP <Wn>, #<imm>, #<nzcv>, <cond>"
},
{
"condition": "sf == 1",
"format": "CCMP <Xn>, #<imm>, #<nzcv>, <cond>"
}
],
"decoder": [
"integer n = UInt(Rn);",
"integer datasize = if sf == '1' then 64 else 32;",
"boolean sub_op = (op == '1');",
"bits(4) condition = cond;",
"bits(4) flags = nzcv;",
"bits(datasize) imm = ZeroExtend(imm5, datasize);"
]
}
],
"name": "CCMP (immediate)",
"description": [
"Conditional Compare (immediate)"
]
}
{
"operation": [
"bits(datasize) operand1 = X[n];",
"bits(datasize) operand2 = X[m];",
"bit carry_in = '0';",
"",
"if ConditionHolds(condition) then",
" if sub_op then",
" operand2 = NOT(operand2);",
" carry_in = '1';",
" (-, flags) = AddWithCarry(operand1, operand2, carry_in);",
"PSTATE. = flags;"
],
"variants": [
{
"pattern": "sf#1 op#1 S#1 1 1 0 1 0 0 1 0 Rm#5 cond#4 0 o2#1 Rn#5 o3#1 nzcv#4",
"formats": [
{
"condition": "sf == 0",
"format": "CCMP <Wn>, <Wm>, #<nzcv>, <cond>"
},
{
"condition": "sf == 1",
"format": "CCMP <Xn>, <Xm>, #<nzcv>, <cond>"
}
],
"decoder": [
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer datasize = if sf == '1' then 64 else 32;",
"boolean sub_op = (op == '1');",
"bits(4) condition = cond;",
"bits(4) flags = nzcv;"
]
}
],
"name": "CCMP (register)",
"description": [
"Conditional Compare (register)"
]
}
{
"operation": null,
"variants": [
{
"pattern": "sf#1 op#1 S#1 1 1 0 1 0 1 0 0 Rm#5 cond#4 0 o2#1 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0",
"format": "CINC <Wd>, <Wn>, <cond>"
},
{
"condition": "sf == 1",
"format": "CINC <Xd>, <Xn>, <cond>"
}
],
"decoder": [
""
]
}
],
"name": "CINC",
"description": [
"Conditional Increment"
]
}
{
"operation": null,
"variants": [
{
"pattern": "sf#1 op#1 S#1 1 1 0 1 0 1 0 0 Rm#5 cond#4 0 o2#1 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0",
"format": "CINV <Wd>, <Wn>, <cond>"
},
{
"condition": "sf == 1",
"format": "CINV <Xd>, <Xn>, <cond>"
}
],
"decoder": [
""
]
}
],
"name": "CINV",
"description": [
"Conditional Invert"
]
}
{
"operation": [
"ClearExclusiveLocal(ProcessorID());"
],
"variants": [
{
"pattern": "1 1 0 1 0 1 0 1 0 0 L#1 op0#2 op1#3 CRn#4 CRm#4 op2#3 Rt#5",
"formats": [
{
"condition": null,
"format": "CLREX {#<imm>}"
}
],
"decoder": [
"// CRm field is ignored"
]
}
],
"name": "CLREX",
"description": [
"Clear Exclusive"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"bits(datasize) result;",
"",
"integer count;",
"for e = 0 to elements-1",
" if countop == CountOp_CLS then",
" count = CountLeadingSignBits(Elem[operand, e, esize]);",
" else",
" count = CountLeadingZeroBits(Elem[operand, e, esize]);",
" Elem[result, e, esize] = count;",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 size#2 1 0 0 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "CLS <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if size == '11' then ReservedValue();",
"integer esize = 8 << UInt(size);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"CountOp countop = if U == '1' then CountOp_CLZ else CountOp_CLS;"
]
}
],
"name": "CLS (vector)",
"description": [
"Count Leading Sign bits (vector)"
]
}
{
"operation": [
"integer result;",
"bits(datasize) operand1 = X[n];",
"",
"if opcode == CountOp_CLZ then",
" result = CountLeadingZeroBits(operand1);",
"else",
" result = CountLeadingSignBits(operand1);",
"",
"X[d] = result;"
],
"variants": [
{
"pattern": "sf#1 1 S#1 1 1 0 1 0 1 1 0 opcode2#5 opcode[5:1]#5 op#1 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0",
"format": "CLS <Wd>, <Wn>"
},
{
"condition": "sf == 1",
"format": "CLS <Xd>, <Xn>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer datasize = if sf == '1' then 64 else 32;",
"CountOp opcode = if op == '0' then CountOp_CLZ else CountOp_CLS;"
]
}
],
"name": "CLS",
"description": [
"Count leading sign bits",
"Rd = CLS(Rn)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"bits(datasize) result;",
"",
"integer count;",
"for e = 0 to elements-1",
" if countop == CountOp_CLS then",
" count = CountLeadingSignBits(Elem[operand, e, esize]);",
" else",
" count = CountLeadingZeroBits(Elem[operand, e, esize]);",
" Elem[result, e, esize] = count;",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 size#2 1 0 0 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "CLZ <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if size == '11' then ReservedValue();",
"integer esize = 8 << UInt(size);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"CountOp countop = if U == '1' then CountOp_CLZ else CountOp_CLS;"
]
}
],
"name": "CLZ (vector)",
"description": [
"Count Leading Zero bits (vector)"
]
}
{
"operation": [
"integer result;",
"bits(datasize) operand1 = X[n];",
"",
"if opcode == CountOp_CLZ then",
" result = CountLeadingZeroBits(operand1);",
"else",
" result = CountLeadingSignBits(operand1);",
"",
"X[d] = result;"
],
"variants": [
{
"pattern": "sf#1 1 S#1 1 1 0 1 0 1 1 0 opcode2#5 opcode[5:1]#5 op#1 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0",
"format": "CLZ <Wd>, <Wn>"
},
{
"condition": "sf == 1",
"format": "CLZ <Xd>, <Xn>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer datasize = if sf == '1' then 64 else 32;",
"CountOp opcode = if op == '0' then CountOp_CLZ else CountOp_CLS;"
]
}
],
"name": "CLZ",
"description": [
"Count leading zero bits",
"Rd = CLZ(Rn)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"bits(datasize) result;",
"bits(esize) element1;",
"bits(esize) element2;",
"boolean test_passed;",
"",
"for e = 0 to elements-1",
" element1 = Elem[operand1, e, esize];",
" element2 = Elem[operand2, e, esize];",
" if and_test then",
" test_passed = !IsZero(element1 AND element2);",
" else",
" test_passed = (element1 == element2);",
" Elem[result, e, esize] = if test_passed then Ones() else Zeros();",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 0 size#2 1 Rm#5 opcode#5 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "CMEQ <V><d>, <V><n>, <V><m>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"if size != '11' then ReservedValue();",
"integer esize = 8 << UInt(size);",
"integer datasize = esize;",
"integer elements = 1;",
"boolean and_test = (U == '0');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 size#2 1 Rm#5 opcode#5 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "CMEQ <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"if size:Q == '110' then ReservedValue();",
"integer esize = 8 << UInt(size);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"boolean and_test = (U == '0');"
]
}
],
"name": "CMEQ (register)",
"description": [
"Compare bitwise Equal (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"bits(datasize) result;",
"integer element;",
"boolean test_passed;",
"",
"for e = 0 to elements-1",
" element = SInt(Elem[operand, e, esize]);",
" case comparison of",
" when CompareOp_GT test_passed = element > 0;",
" when CompareOp_GE test_passed = element >= 0;",
" when CompareOp_EQ test_passed = element == 0;",
" when CompareOp_LE test_passed = element <= 0;",
" when CompareOp_LT test_passed = element < 0;",
" Elem[result, e, esize] = if test_passed then Ones() else Zeros();",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 0 size#2 1 0 0 0 0 0 1 0 0 op#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "CMEQ <V><d>, <V><n>, #0"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if size != '11' then ReservedValue();",
"integer esize = 8 << UInt(size);",
"integer datasize = esize;",
"integer elements = 1;",
"",
"CompareOp comparison;",
"case op:U of",
" when '00' comparison = CompareOp_GT;",
" when '01' comparison = CompareOp_GE;",
" when '10' comparison = CompareOp_EQ;",
" when '11' comparison = CompareOp_LE;"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 size#2 1 0 0 0 0 0 1 0 0 op#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "CMEQ <Vd>.<T>, <Vn>.<T>, #0"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if size:Q == '110' then ReservedValue();",
"integer esize = 8 << UInt(size);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"CompareOp comparison;",
"case op:U of",
" when '00' comparison = CompareOp_GT;",
" when '01' comparison = CompareOp_GE;",
" when '10' comparison = CompareOp_EQ;",
" when '11' comparison = CompareOp_LE;"
]
}
],
"name": "CMEQ (zero)",
"description": [
"Compare bitwise Equal to zero (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"bits(datasize) result;",
"integer element1;",
"integer element2;",
"boolean test_passed;",
"",
"for e = 0 to elements-1",
" element1 = Int(Elem[operand1, e, esize], unsigned);",
" element2 = Int(Elem[operand2, e, esize], unsigned);",
" test_passed = if cmp_eq then element1 >= element2 else element1 > element2;",
" Elem[result, e, esize] = if test_passed then Ones() else Zeros();",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 0 size#2 1 Rm#5 0 0 1 1 eq#1 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "CMGE <V><d>, <V><n>, <V><m>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"if size != '11' then ReservedValue();",
"integer esize = 8 << UInt(size);",
"integer datasize = esize;",
"integer elements = 1;",
"boolean unsigned = (U == '1');",
"boolean cmp_eq = (eq == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 size#2 1 Rm#5 0 0 1 1 eq#1 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "CMGE <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"if size:Q == '110' then ReservedValue();",
"integer esize = 8 << UInt(size);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"boolean unsigned = (U == '1');",
"boolean cmp_eq = (eq == '1');"
]
}
],
"name": "CMGE (register)",
"description": [
"Compare signed Greater than or Equal (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"bits(datasize) result;",
"integer element;",
"boolean test_passed;",
"",
"for e = 0 to elements-1",
" element = SInt(Elem[operand, e, esize]);",
" case comparison of",
" when CompareOp_GT test_passed = element > 0;",
" when CompareOp_GE test_passed = element >= 0;",
" when CompareOp_EQ test_passed = element == 0;",
" when CompareOp_LE test_passed = element <= 0;",
" when CompareOp_LT test_passed = element < 0;",
" Elem[result, e, esize] = if test_passed then Ones() else Zeros();",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 0 size#2 1 0 0 0 0 0 1 0 0 op#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "CMGE <V><d>, <V><n>, #0"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if size != '11' then ReservedValue();",
"integer esize = 8 << UInt(size);",
"integer datasize = esize;",
"integer elements = 1;",
"",
"CompareOp comparison;",
"case op:U of",
" when '00' comparison = CompareOp_GT;",
" when '01' comparison = CompareOp_GE;",
" when '10' comparison = CompareOp_EQ;",
" when '11' comparison = CompareOp_LE;"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 size#2 1 0 0 0 0 0 1 0 0 op#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "CMGE <Vd>.<T>, <Vn>.<T>, #0"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if size:Q == '110' then ReservedValue();",
"integer esize = 8 << UInt(size);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"CompareOp comparison;",
"case op:U of",
" when '00' comparison = CompareOp_GT;",
" when '01' comparison = CompareOp_GE;",
" when '10' comparison = CompareOp_EQ;",
" when '11' comparison = CompareOp_LE;"
]
}
],
"name": "CMGE (zero)",
"description": [
"Compare signed Greater than or Equal to zero (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"bits(datasize) result;",
"integer element1;",
"integer element2;",
"boolean test_passed;",
"",
"for e = 0 to elements-1",
" element1 = Int(Elem[operand1, e, esize], unsigned);",
" element2 = Int(Elem[operand2, e, esize], unsigned);",
" test_passed = if cmp_eq then element1 >= element2 else element1 > element2;",
" Elem[result, e, esize] = if test_passed then Ones() else Zeros();",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 0 size#2 1 Rm#5 0 0 1 1 eq#1 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "CMGT <V><d>, <V><n>, <V><m>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"if size != '11' then ReservedValue();",
"integer esize = 8 << UInt(size);",
"integer datasize = esize;",
"integer elements = 1;",
"boolean unsigned = (U == '1');",
"boolean cmp_eq = (eq == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 size#2 1 Rm#5 0 0 1 1 eq#1 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "CMGT <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"if size:Q == '110' then ReservedValue();",
"integer esize = 8 << UInt(size);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"boolean unsigned = (U == '1');",
"boolean cmp_eq = (eq == '1');"
]
}
],
"name": "CMGT (register)",
"description": [
"Compare signed Greater than (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"bits(datasize) result;",
"integer element;",
"boolean test_passed;",
"",
"for e = 0 to elements-1",
" element = SInt(Elem[operand, e, esize]);",
" case comparison of",
" when CompareOp_GT test_passed = element > 0;",
" when CompareOp_GE test_passed = element >= 0;",
" when CompareOp_EQ test_passed = element == 0;",
" when CompareOp_LE test_passed = element <= 0;",
" when CompareOp_LT test_passed = element < 0;",
" Elem[result, e, esize] = if test_passed then Ones() else Zeros();",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 0 size#2 1 0 0 0 0 0 1 0 0 op#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "CMGT <V><d>, <V><n>, #0"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if size != '11' then ReservedValue();",
"integer esize = 8 << UInt(size);",
"integer datasize = esize;",
"integer elements = 1;",
"",
"CompareOp comparison;",
"case op:U of",
" when '00' comparison = CompareOp_GT;",
" when '01' comparison = CompareOp_GE;",
" when '10' comparison = CompareOp_EQ;",
" when '11' comparison = CompareOp_LE;"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 size#2 1 0 0 0 0 0 1 0 0 op#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "CMGT <Vd>.<T>, <Vn>.<T>, #0"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if size:Q == '110' then ReservedValue();",
"integer esize = 8 << UInt(size);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"CompareOp comparison;",
"case op:U of",
" when '00' comparison = CompareOp_GT;",
" when '01' comparison = CompareOp_GE;",
" when '10' comparison = CompareOp_EQ;",
" when '11' comparison = CompareOp_LE;"
]
}
],
"name": "CMGT (zero)",
"description": [
"Compare signed Greater than zero (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"bits(datasize) result;",
"integer element1;",
"integer element2;",
"boolean test_passed;",
"",
"for e = 0 to elements-1",
" element1 = Int(Elem[operand1, e, esize], unsigned);",
" element2 = Int(Elem[operand2, e, esize], unsigned);",
" test_passed = if cmp_eq then element1 >= element2 else element1 > element2;",
" Elem[result, e, esize] = if test_passed then Ones() else Zeros();",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 0 size#2 1 Rm#5 0 0 1 1 eq#1 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "CMHI <V><d>, <V><n>, <V><m>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"if size != '11' then ReservedValue();",
"integer esize = 8 << UInt(size);",
"integer datasize = esize;",
"integer elements = 1;",
"boolean unsigned = (U == '1');",
"boolean cmp_eq = (eq == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 size#2 1 Rm#5 0 0 1 1 eq#1 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "CMHI <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"if size:Q == '110' then ReservedValue();",
"integer esize = 8 << UInt(size);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"boolean unsigned = (U == '1');",
"boolean cmp_eq = (eq == '1');"
]
}
],
"name": "CMHI (register)",
"description": [
"Compare unsigned Higher (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"bits(datasize) result;",
"integer element1;",
"integer element2;",
"boolean test_passed;",
"",
"for e = 0 to elements-1",
" element1 = Int(Elem[operand1, e, esize], unsigned);",
" element2 = Int(Elem[operand2, e, esize], unsigned);",
" test_passed = if cmp_eq then element1 >= element2 else element1 > element2;",
" Elem[result, e, esize] = if test_passed then Ones() else Zeros();",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 0 size#2 1 Rm#5 0 0 1 1 eq#1 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "CMHS <V><d>, <V><n>, <V><m>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"if size != '11' then ReservedValue();",
"integer esize = 8 << UInt(size);",
"integer datasize = esize;",
"integer elements = 1;",
"boolean unsigned = (U == '1');",
"boolean cmp_eq = (eq == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 size#2 1 Rm#5 0 0 1 1 eq#1 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "CMHS <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"if size:Q == '110' then ReservedValue();",
"integer esize = 8 << UInt(size);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"boolean unsigned = (U == '1');",
"boolean cmp_eq = (eq == '1');"
]
}
],
"name": "CMHS (register)",
"description": [
"Compare unsigned Higher or Same (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"bits(datasize) result;",
"integer element;",
"boolean test_passed;",
"",
"for e = 0 to elements-1",
" element = SInt(Elem[operand, e, esize]);",
" case comparison of",
" when CompareOp_GT test_passed = element > 0;",
" when CompareOp_GE test_passed = element >= 0;",
" when CompareOp_EQ test_passed = element == 0;",
" when CompareOp_LE test_passed = element <= 0;",
" when CompareOp_LT test_passed = element < 0;",
" Elem[result, e, esize] = if test_passed then Ones() else Zeros();",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 0 size#2 1 0 0 0 0 0 1 0 0 op#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "CMLE <V><d>, <V><n>, #0"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if size != '11' then ReservedValue();",
"integer esize = 8 << UInt(size);",
"integer datasize = esize;",
"integer elements = 1;",
"",
"CompareOp comparison;",
"case op:U of",
" when '00' comparison = CompareOp_GT;",
" when '01' comparison = CompareOp_GE;",
" when '10' comparison = CompareOp_EQ;",
" when '11' comparison = CompareOp_LE;"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 size#2 1 0 0 0 0 0 1 0 0 op#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "CMLE <Vd>.<T>, <Vn>.<T>, #0"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if size:Q == '110' then ReservedValue();",
"integer esize = 8 << UInt(size);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"CompareOp comparison;",
"case op:U of",
" when '00' comparison = CompareOp_GT;",
" when '01' comparison = CompareOp_GE;",
" when '10' comparison = CompareOp_EQ;",
" when '11' comparison = CompareOp_LE;"
]
}
],
"name": "CMLE (zero)",
"description": [
"Compare signed Less than or Equal to zero (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"bits(datasize) result;",
"integer element;",
"boolean test_passed;",
"",
"for e = 0 to elements-1",
" element = SInt(Elem[operand, e, esize]);",
" case comparison of",
" when CompareOp_GT test_passed = element > 0;",
" when CompareOp_GE test_passed = element >= 0;",
" when CompareOp_EQ test_passed = element == 0;",
" when CompareOp_LE test_passed = element <= 0;",
" when CompareOp_LT test_passed = element < 0;",
" Elem[result, e, esize] = if test_passed then Ones() else Zeros();",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 0 size#2 1 0 0 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "CMLT <V><d>, <V><n>, #0"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if size != '11' then ReservedValue();",
"integer esize = 8 << UInt(size);",
"integer datasize = esize;",
"integer elements = 1;",
"",
"CompareOp comparison = CompareOp_LT;"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 size#2 1 0 0 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "CMLT <Vd>.<T>, <Vn>.<T>, #0"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if size:Q == '110' then ReservedValue();",
"integer esize = 8 << UInt(size);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"CompareOp comparison = CompareOp_LT;"
]
}
],
"name": "CMLT (zero)",
"description": [
"Compare signed Less than zero (vector)"
]
}
{
"operation": null,
"variants": [
{
"pattern": "sf#1 op#1 S#1 0 1 0 1 1 opt#2 1 Rm#5 option#3 imm3#3 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0",
"format": "CMN <Wn|WSP>, <Wm>{, <extend> {#<amount>}}"
},
{
"condition": "sf == 1",
"format": "CMN <Xn|SP>, <R><m>{, <extend> {#<amount>}}"
}
],
"decoder": [
""
]
}
],
"name": "CMN (extended register)",
"description": [
"Compare Negative (extended register)"
]
}
{
"operation": null,
"variants": [
{
"pattern": "sf#1 op#1 S#1 1 0 0 0 1 shift#2 imm12#12 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0",
"format": "CMN <Wn|WSP>, #<imm>{, <shift>}"
},
{
"condition": "sf == 1",
"format": "CMN <Xn|SP>, #<imm>{, <shift>}"
}
],
"decoder": [
""
]
}
],
"name": "CMN (immediate)",
"description": [
"Compare Negative (immediate)"
]
}
{
"operation": null,
"variants": [
{
"pattern": "sf#1 op#1 S#1 0 1 0 1 1 shift#2 0 Rm#5 imm6#6 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0",
"format": "CMN <Wn>, <Wm>{, <shift> #<amount>}"
},
{
"condition": "sf == 1",
"format": "CMN <Xn>, <Xm>{, <shift> #<amount>}"
}
],
"decoder": [
""
]
}
],
"name": "CMN (shifted register)",
"description": [
"Compare Negative (shifted register)"
]
}
{
"operation": null,
"variants": [
{
"pattern": "sf#1 op#1 S#1 0 1 0 1 1 opt#2 1 Rm#5 option#3 imm3#3 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0",
"format": "CMP <Wn|WSP>, <Wm>{, <extend> {#<amount>}}"
},
{
"condition": "sf == 1",
"format": "CMP <Xn|SP>, <R><m>{, <extend> {#<amount>}}"
}
],
"decoder": [
""
]
}
],
"name": "CMP (extended register)",
"description": [
"Compare (extended register)"
]
}
{
"operation": null,
"variants": [
{
"pattern": "sf#1 op#1 S#1 1 0 0 0 1 shift#2 imm12#12 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0",
"format": "CMP <Wn|WSP>, #<imm>{, <shift>}"
},
{
"condition": "sf == 1",
"format": "CMP <Xn|SP>, #<imm>{, <shift>}"
}
],
"decoder": [
""
]
}
],
"name": "CMP (immediate)",
"description": [
"Compare (immediate)"
]
}
{
"operation": null,
"variants": [
{
"pattern": "sf#1 op#1 S#1 0 1 0 1 1 shift#2 0 Rm#5 imm6#6 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0",
"format": "CMP <Wn>, <Wm>{, <shift> #<amount>}"
},
{
"condition": "sf == 1",
"format": "CMP <Xn>, <Xm>{, <shift> #<amount>}"
}
],
"decoder": [
""
]
}
],
"name": "CMP (shifted register)",
"description": [
"Compare (shifted register)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"bits(datasize) result;",
"bits(esize) element1;",
"bits(esize) element2;",
"boolean test_passed;",
"",
"for e = 0 to elements-1",
" element1 = Elem[operand1, e, esize];",
" element2 = Elem[operand2, e, esize];",
" if and_test then",
" test_passed = !IsZero(element1 AND element2);",
" else",
" test_passed = (element1 == element2);",
" Elem[result, e, esize] = if test_passed then Ones() else Zeros();",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 0 size#2 1 Rm#5 opcode#5 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "CMTST <V><d>, <V><n>, <V><m>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"if size != '11' then ReservedValue();",
"integer esize = 8 << UInt(size);",
"integer datasize = esize;",
"integer elements = 1;",
"boolean and_test = (U == '0');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 size#2 1 Rm#5 opcode#5 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "CMTST <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"if size:Q == '110' then ReservedValue();",
"integer esize = 8 << UInt(size);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"boolean and_test = (U == '0');"
]
}
],
"name": "CMTST",
"description": [
"Compare bitwise Test bits nonzero (vector)"
]
}
{
"operation": null,
"variants": [
{
"pattern": "sf#1 op#1 S#1 1 1 0 1 0 1 0 0 Rm#5 cond#4 0 o2#1 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0",
"format": "CNEG <Wd>, <Wn>, <cond>"
},
{
"condition": "sf == 1",
"format": "CNEG <Xd>, <Xn>, <cond>"
}
],
"decoder": [
""
]
}
],
"name": "CNEG",
"description": [
"Conditional Negate"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"bits(datasize) result;",
"",
"integer count;",
"for e = 0 to elements-1",
" count = BitCount(Elem[operand, e, esize]);",
" Elem[result, e, esize] = count;",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 size#2 1 0 0 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "CNT <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if size != '00' then ReservedValue();",
"integer esize = 8;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV 8;"
]
}
],
"name": "CNT",
"description": [
"Population Count per byte"
]
}
{
"operation": [
"if !HaveCRCExt() then",
" UnallocatedEncoding();",
"",
"bits(32) acc = X[n]; // accumulator",
"bits(size) val = X[m]; // input value",
"bits(32) poly = (if crc32c then 0x1EDC6F41 else 0x04C11DB7)<31:0>;",
"",
"bits(32+size) tempacc = BitReverse(acc) : Zeros(size);",
"bits(size+32) tempval = BitReverse(val) : Zeros(32);",
"",
"// Poly32Mod2 on a bitstring does a polynomial Modulus over {0,1} operation",
"X[d] = BitReverse(Poly32Mod2(tempacc EOR tempval, poly));"
],
"variants": [
{
"pattern": "sf#1 op#1 S#1 1 1 0 1 0 1 1 0 Rm#5 opcode2<5:3>#3 C#1 sz#2 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0 && sz == 00",
"format": "CRC32B <Wd>, <Wn>, <Wm>"
},
{
"condition": "sf == 0 && sz == 01",
"format": "CRC32H <Wd>, <Wn>, <Wm>"
},
{
"condition": "sf == 0 && sz == 10",
"format": "CRC32W <Wd>, <Wn>, <Wm>"
},
{
"condition": "sf == 1 && sz == 11",
"format": "CRC32X <Wd>, <Wn>, <Xm>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"if sf == '1' && sz != '11' then UnallocatedEncoding();",
"if sf == '0' && sz == '11' then UnallocatedEncoding();",
"integer size = 8 << UInt(sz); // 2-bit size field -> 8, 16, 32, 64",
"boolean crc32c = (C == '1');"
]
}
],
"name": "CRC32B, CRC32H, CRC32W, CRC32X",
"description": [
"CRC32 checksum"
]
}
{
"operation": [
"if !HaveCRCExt() then",
" UnallocatedEncoding();",
"",
"bits(32) acc = X[n]; // accumulator",
"bits(size) val = X[m]; // input value",
"bits(32) poly = (if crc32c then 0x1EDC6F41 else 0x04C11DB7)<31:0>;",
"",
"bits(32+size) tempacc = BitReverse(acc) : Zeros(size);",
"bits(size+32) tempval = BitReverse(val) : Zeros(32);",
"",
"// Poly32Mod2 on a bitstring does a polynomial Modulus over {0,1} operation",
"X[d] = BitReverse(Poly32Mod2(tempacc EOR tempval, poly));"
],
"variants": [
{
"pattern": "sf#1 op#1 S#1 1 1 0 1 0 1 1 0 Rm#5 opcode2<5:3>#3 C#1 sz#2 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0 && sz == 00",
"format": "CRC32CB <Wd>, <Wn>, <Wm>"
},
{
"condition": "sf == 0 && sz == 01",
"format": "CRC32CH <Wd>, <Wn>, <Wm>"
},
{
"condition": "sf == 0 && sz == 10",
"format": "CRC32CW <Wd>, <Wn>, <Wm>"
},
{
"condition": "sf == 1 && sz == 11",
"format": "CRC32CX <Wd>, <Wn>, <Xm>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"if sf == '1' && sz != '11' then UnallocatedEncoding();",
"if sf == '0' && sz == '11' then UnallocatedEncoding();",
"integer size = 8 << UInt(sz); // 2-bit size field -> 8, 16, 32, 64",
"boolean crc32c = (C == '1');"
]
}
],
"name": "CRC32CB, CRC32CH, CRC32CW, CRC32CX",
"description": [
"CRC32C checksum"
]
}
{
"operation": [
"bits(datasize) result;",
"bits(datasize) operand1 = X[n];",
"bits(datasize) operand2 = X[m];",
"",
"if ConditionHolds(condition) then",
" result = operand1;",
"else",
" result = operand2;",
" if else_inv then result = NOT(result);",
" if else_inc then result = result + 1;",
"",
"X[d] = result;"
],
"variants": [
{
"pattern": "sf#1 op#1 S#1 1 1 0 1 0 1 0 0 Rm#5 cond#4 0 o2#1 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0",
"format": "CSEL <Wd>, <Wn>, <Wm>, <cond>"
},
{
"condition": "sf == 1",
"format": "CSEL <Xd>, <Xn>, <Xm>, <cond>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer datasize = if sf == '1' then 64 else 32;",
"bits(4) condition = cond;",
"boolean else_inv = (op == '1');",
"boolean else_inc = (o2 == '1');"
]
}
],
"name": "CSEL",
"description": [
"Conditional Select"
]
}
{
"operation": null,
"variants": [
{
"pattern": "sf#1 op#1 S#1 1 1 0 1 0 1 0 0 Rm#5 cond#4 0 o2#1 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0",
"format": "CSET <Wd>, <cond>"
},
{
"condition": "sf == 1",
"format": "CSET <Xd>, <cond>"
}
],
"decoder": [
""
]
}
],
"name": "CSET",
"description": [
"Conditional Set"
]
}
{
"operation": null,
"variants": [
{
"pattern": "sf#1 op#1 S#1 1 1 0 1 0 1 0 0 Rm#5 cond#4 0 o2#1 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0",
"format": "CSETM <Wd>, <cond>"
},
{
"condition": "sf == 1",
"format": "CSETM <Xd>, <cond>"
}
],
"decoder": [
""
]
}
],
"name": "CSETM",
"description": [
"Conditional Set Mask"
]
}
{
"operation": [
"bits(datasize) result;",
"bits(datasize) operand1 = X[n];",
"bits(datasize) operand2 = X[m];",
"",
"if ConditionHolds(condition) then",
" result = operand1;",
"else",
" result = operand2;",
" if else_inv then result = NOT(result);",
" if else_inc then result = result + 1;",
"",
"X[d] = result;"
],
"variants": [
{
"pattern": "sf#1 op#1 S#1 1 1 0 1 0 1 0 0 Rm#5 cond#4 0 o2#1 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0",
"format": "CSINC <Wd>, <Wn>, <Wm>, <cond>"
},
{
"condition": "sf == 1",
"format": "CSINC <Xd>, <Xn>, <Xm>, <cond>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer datasize = if sf == '1' then 64 else 32;",
"bits(4) condition = cond;",
"boolean else_inv = (op == '1');",
"boolean else_inc = (o2 == '1');"
]
}
],
"name": "CSINC",
"description": [
"Conditional Select Increment"
]
}
{
"operation": [
"bits(datasize) result;",
"bits(datasize) operand1 = X[n];",
"bits(datasize) operand2 = X[m];",
"",
"if ConditionHolds(condition) then",
" result = operand1;",
"else",
" result = operand2;",
" if else_inv then result = NOT(result);",
" if else_inc then result = result + 1;",
"",
"X[d] = result;"
],
"variants": [
{
"pattern": "sf#1 op#1 S#1 1 1 0 1 0 1 0 0 Rm#5 cond#4 0 o2#1 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0",
"format": "CSINV <Wd>, <Wn>, <Wm>, <cond>"
},
{
"condition": "sf == 1",
"format": "CSINV <Xd>, <Xn>, <Xm>, <cond>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer datasize = if sf == '1' then 64 else 32;",
"bits(4) condition = cond;",
"boolean else_inv = (op == '1');",
"boolean else_inc = (o2 == '1');"
]
}
],
"name": "CSINV",
"description": [
"Conditional Select Invert"
]
}
{
"operation": [
"bits(datasize) result;",
"bits(datasize) operand1 = X[n];",
"bits(datasize) operand2 = X[m];",
"",
"if ConditionHolds(condition) then",
" result = operand1;",
"else",
" result = operand2;",
" if else_inv then result = NOT(result);",
" if else_inc then result = result + 1;",
"",
"X[d] = result;"
],
"variants": [
{
"pattern": "sf#1 op#1 S#1 1 1 0 1 0 1 0 0 Rm#5 cond#4 0 o2#1 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0",
"format": "CSNEG <Wd>, <Wn>, <Wm>, <cond>"
},
{
"condition": "sf == 1",
"format": "CSNEG <Xd>, <Xn>, <Xm>, <cond>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer datasize = if sf == '1' then 64 else 32;",
"bits(4) condition = cond;",
"boolean else_inv = (op == '1');",
"boolean else_inc = (o2 == '1');"
]
}
],
"name": "CSNEG",
"description": [
"Conditional Select Negation"
]
}
{
"operation": null,
"variants": [
{
"pattern": "1 1 0 1 0 1 0 1 0 0 L#1 op0#2 op1#3 CRn#4 CRm#4 op2#3 Rt#5",
"formats": [
{
"condition": null,
"format": "DC <dc_op>, <Xt>"
}
],
"decoder": [
""
]
}
],
"name": "DC",
"description": [
"Data Cache operation"
]
}
{
"operation": [
"DCPSInstruction(target_level);"
],
"variants": [
{
"pattern": "1 1 0 1 0 1 0 0 opc#3 imm16#16 op2#3 LL#2",
"formats": [
{
"condition": null,
"format": "DCPS1 {#<imm>}"
}
],
"decoder": [
"bits(2) target_level = LL;",
"if LL == '00' then UnallocatedEncoding();",
"if !Halted() then AArch64.UndefinedFault();"
]
}
],
"name": "DCPS1",
"description": [
"Debug Change PE State to EL1."
]
}
{
"operation": [
"DCPSInstruction(target_level);"
],
"variants": [
{
"pattern": "1 1 0 1 0 1 0 0 opc#3 imm16#16 op2#3 LL#2",
"formats": [
{
"condition": null,
"format": "DCPS2 {#<imm>}"
}
],
"decoder": [
"bits(2) target_level = LL;",
"if LL == '00' then UnallocatedEncoding();",
"if !Halted() then AArch64.UndefinedFault();"
]
}
],
"name": "DCPS2",
"description": [
"Debug Change PE State to EL2."
]
}
{
"operation": [
"DCPSInstruction(target_level);"
],
"variants": [
{
"pattern": "1 1 0 1 0 1 0 0 opc#3 imm16#16 op2#3 LL#2",
"formats": [
{
"condition": null,
"format": "DCPS3 {#<imm>}"
}
],
"decoder": [
"bits(2) target_level = LL;",
"if LL == '00' then UnallocatedEncoding();",
"if !Halted() then AArch64.UndefinedFault();"
]
}
],
"name": "DCPS3",
"description": [
"Debug Change PE State to EL3"
]
}
{
"operation": [
"case op of",
" when MemBarrierOp_DSB",
" DataSynchronizationBarrier(domain, types);",
" when MemBarrierOp_DMB",
" DataMemoryBarrier(domain, types);",
" when MemBarrierOp_ISB",
" InstructionSynchronizationBarrier();"
],
"variants": [
{
"pattern": "1 1 0 1 0 1 0 1 0 0 L#1 op0#2 op1#3 CRn#4 CRm#4 1 opc#2 Rt#5",
"formats": [
{
"condition": null,
"format": "DMB <option>|#<imm>"
}
],
"decoder": [
"MemBarrierOp op;",
"MBReqDomain domain;",
"MBReqTypes types;",
"",
"case opc of",
" when '00' op = MemBarrierOp_DSB;",
" when '01' op = MemBarrierOp_DMB;",
" when '10' op = MemBarrierOp_ISB;",
" otherwise UnallocatedEncoding();",
"",
"case CRm<3:2> of",
" when '00' domain = MBReqDomain_OuterShareable;",
" when '01' domain = MBReqDomain_Nonshareable;",
" when '10' domain = MBReqDomain_InnerShareable;",
" when '11' domain = MBReqDomain_FullSystem;",
"",
"case CRm<1:0> of",
" when '01' types = MBReqTypes_Reads;",
" when '10' types = MBReqTypes_Writes;",
" when '11' types = MBReqTypes_All;",
" otherwise",
" types = MBReqTypes_All;",
" domain = MBReqDomain_FullSystem;"
]
}
],
"name": "DMB",
"description": [
"Data Memory Barrier"
]
}
{
"operation": [
"DRPSInstruction();"
],
"variants": [
{
"pattern": "1 1 0 1 0 1 1 opc#4 op2#5 op3#6 Rt#5 op4#5",
"formats": [
{
"condition": null,
"format": "DRPS"
}
],
"decoder": [
"if !Halted() || PSTATE.EL == EL0 then UnallocatedEncoding();"
]
}
],
"name": "DRPS",
"description": [
"Debug restore process state"
]
}
{
"operation": [
"case op of",
" when MemBarrierOp_DSB",
" DataSynchronizationBarrier(domain, types);",
" when MemBarrierOp_DMB",
" DataMemoryBarrier(domain, types);",
" when MemBarrierOp_ISB",
" InstructionSynchronizationBarrier();"
],
"variants": [
{
"pattern": "1 1 0 1 0 1 0 1 0 0 L#1 op0#2 op1#3 CRn#4 CRm#4 1 opc#2 Rt#5",
"formats": [
{
"condition": null,
"format": "DSB <option>|#<imm>"
}
],
"decoder": [
"MemBarrierOp op;",
"MBReqDomain domain;",
"MBReqTypes types;",
"",
"case opc of",
" when '00' op = MemBarrierOp_DSB;",
" when '01' op = MemBarrierOp_DMB;",
" when '10' op = MemBarrierOp_ISB;",
" otherwise UnallocatedEncoding();",
"",
"case CRm<3:2> of",
" when '00' domain = MBReqDomain_OuterShareable;",
" when '01' domain = MBReqDomain_Nonshareable;",
" when '10' domain = MBReqDomain_InnerShareable;",
" when '11' domain = MBReqDomain_FullSystem;",
"",
"case CRm<1:0> of",
" when '01' types = MBReqTypes_Reads;",
" when '10' types = MBReqTypes_Writes;",
" when '11' types = MBReqTypes_All;",
" otherwise",
" types = MBReqTypes_All;",
" domain = MBReqDomain_FullSystem;"
]
}
],
"name": "DSB",
"description": [
"Data Synchronization Barrier"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(idxdsize) operand = V[n];",
"bits(datasize) result;",
"bits(esize) element;",
"",
"element = Elem[operand, index, esize];",
"for e = 0 to elements-1",
" Elem[result, e, esize] = element;",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 op#1 1 1 1 1 0 0 0 0 imm5#5 0 imm4#4 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "DUP <V><d>, <Vn>.<T>[<index>]"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer size = LowestSetBit(imm5);",
"if size > 3 then UnallocatedEncoding();",
"",
"integer index = UInt(imm5<4:size+1>);",
"integer idxdsize = if imm5<4> == '1' then 128 else 64; ",
"",
"integer esize = 8 << size;",
"integer datasize = esize;",
"integer elements = 1;"
]
},
{
"pattern": "0 Q#1 op#1 0 1 1 1 0 0 0 0 imm5#5 0 imm4#4 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "DUP <Vd>.<T>, <Vn>.<Ts>[<index>]"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer size = LowestSetBit(imm5);",
"if size > 3 then UnallocatedEncoding();",
"",
"integer index = UInt(imm5<4:size+1>);",
"integer idxdsize = if imm5<4> == '1' then 128 else 64; ",
"",
"if size == 3 && Q == '0' then ReservedValue();",
"integer esize = 8 << size;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;"
]
}
],
"name": "DUP (element)",
"description": [
"Duplicate vector element to vector or scalar"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(esize) element = X[n];",
"bits(datasize) result;",
"",
"for e = 0 to elements-1",
" Elem[result, e, esize] = element;",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 Q#1 op#1 0 1 1 1 0 0 0 0 imm5#5 0 imm4#4 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "DUP <Vd>.<T>, <R><n>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer size = LowestSetBit(imm5);",
"if size > 3 then UnallocatedEncoding();",
"",
"// imm5<4:size+1> is IGNORED",
"",
"if size == 3 && Q == '0' then ReservedValue();",
"integer esize = 8 << size;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;"
]
}
],
"name": "DUP (general)",
"description": [
"Duplicate general-purpose register to vector"
]
}
{
"operation": [
"bits(datasize) operand1 = X[n];",
"bits(datasize) operand2 = ShiftReg(m, shift_type, shift_amount);",
"",
"if invert then operand2 = NOT(operand2);",
"",
"case op of",
" when LogicalOp_AND result = operand1 AND operand2;",
" when LogicalOp_ORR result = operand1 OR operand2;",
" when LogicalOp_EOR result = operand1 EOR operand2;",
"",
"if setflags then",
" PSTATE. = result:IsZeroBit(result):'00';",
"",
"X[d] = result;"
],
"variants": [
{
"pattern": "sf#1 opc#2 0 1 0 1 0 shift#2 N#1 Rm#5 imm6#6 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0",
"format": "EON <Wd>, <Wn>, <Wm>{, <shift> #<amount>}"
},
{
"condition": "sf == 1",
"format": "EON <Xd>, <Xn>, <Xm>{, <shift> #<amount>}"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer datasize = if sf == '1' then 64 else 32;",
"boolean setflags;",
"LogicalOp op;",
"case opc of",
" when '00' op = LogicalOp_AND; setflags = FALSE;",
" when '01' op = LogicalOp_ORR; setflags = FALSE;",
" when '10' op = LogicalOp_EOR; setflags = FALSE;",
" when '11' op = LogicalOp_AND; setflags = TRUE;",
"",
"if sf == '0' && imm6<5> == '1' then ReservedValue();",
"",
"ShiftType shift_type = DecodeShift(shift);",
"integer shift_amount = UInt(imm6);",
"boolean invert = (N == '1');"
]
}
],
"name": "EON (shifted register)",
"description": [
"Bitwise Exclusive OR NOT (shifted register)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand1;",
"bits(datasize) operand2;",
"bits(datasize) operand3;",
"bits(datasize) operand4 = V[n];",
"",
"case op of",
" when VBitOp_VEOR",
" operand1 = V[m];",
" operand2 = Zeros();",
" operand3 = Ones();",
" when VBitOp_VBSL",
" operand1 = V[m];",
" operand2 = operand1;",
" operand3 = V[d];",
" when VBitOp_VBIT",
" operand1 = V[d];",
" operand2 = operand1;",
" operand3 = V[m];",
" when VBitOp_VBIF",
" operand1 = V[d];",
" operand2 = operand1;",
" operand3 = NOT(V[m]);",
"",
"V[d] = operand1 EOR ((operand2 EOR operand4) AND operand3);"
],
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 opc2#2 1 Rm#5 opcode#5 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "EOR <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 8;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"VBitOp op;",
"",
"case opc2 of",
" when '00' op = VBitOp_VEOR;",
" when '01' op = VBitOp_VBSL;",
" when '10' op = VBitOp_VBIT;",
" when '11' op = VBitOp_VBIF;"
]
}
],
"name": "EOR (vector)",
"description": [
"Bitwise Exclusive OR (vector)"
]
}
{
"operation": [
"bits(datasize) result;",
"bits(datasize) operand1 = X[n];",
"bits(datasize) operand2 = imm;",
"",
"case op of",
" when LogicalOp_AND result = operand1 AND operand2;",
" when LogicalOp_ORR result = operand1 OR operand2;",
" when LogicalOp_EOR result = operand1 EOR operand2;",
"",
"if setflags then",
" PSTATE. = result:IsZeroBit(result):'00';",
"",
"if d == 31 && !setflags then",
" SP[] = result;",
"else",
" X[d] = result;"
],
"variants": [
{
"pattern": "sf#1 opc#2 1 0 0 1 0 0 N#1 immr#6 imms#6 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0 && N == 0",
"format": "EOR <Wd|WSP>, <Wn>, #<imm>"
},
{
"condition": "sf == 1",
"format": "EOR <Xd|SP>, <Xn>, #<imm>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer datasize = if sf == '1' then 64 else 32;",
"boolean setflags;",
"LogicalOp op;",
"case opc of",
" when '00' op = LogicalOp_AND; setflags = FALSE;",
" when '01' op = LogicalOp_ORR; setflags = FALSE;",
" when '10' op = LogicalOp_EOR; setflags = FALSE;",
" when '11' op = LogicalOp_AND; setflags = TRUE;",
"",
"bits(datasize) imm;",
"if sf == '0' && N != '0' then ReservedValue();",
"(imm, -) = DecodeBitMasks(N, imms, immr, TRUE);"
]
}
],
"name": "EOR (immediate)",
"description": [
"Bitwise Exclusive OR (immediate)"
]
}
{
"operation": [
"bits(datasize) operand1 = X[n];",
"bits(datasize) operand2 = ShiftReg(m, shift_type, shift_amount);",
"",
"if invert then operand2 = NOT(operand2);",
"",
"case op of",
" when LogicalOp_AND result = operand1 AND operand2;",
" when LogicalOp_ORR result = operand1 OR operand2;",
" when LogicalOp_EOR result = operand1 EOR operand2;",
"",
"if setflags then",
" PSTATE. = result:IsZeroBit(result):'00';",
"",
"X[d] = result;"
],
"variants": [
{
"pattern": "sf#1 opc#2 0 1 0 1 0 shift#2 N#1 Rm#5 imm6#6 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0",
"format": "EOR <Wd>, <Wn>, <Wm>{, <shift> #<amount>}"
},
{
"condition": "sf == 1",
"format": "EOR <Xd>, <Xn>, <Xm>{, <shift> #<amount>}"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer datasize = if sf == '1' then 64 else 32;",
"boolean setflags;",
"LogicalOp op;",
"case opc of",
" when '00' op = LogicalOp_AND; setflags = FALSE;",
" when '01' op = LogicalOp_ORR; setflags = FALSE;",
" when '10' op = LogicalOp_EOR; setflags = FALSE;",
" when '11' op = LogicalOp_AND; setflags = TRUE;",
"",
"if sf == '0' && imm6<5> == '1' then ReservedValue();",
"",
"ShiftType shift_type = DecodeShift(shift);",
"integer shift_amount = UInt(imm6);",
"boolean invert = (N == '1');"
]
}
],
"name": "EOR (shifted register)",
"description": [
"Bitwise Exclusive OR (shifted register)"
]
}
{
"operation": [
"AArch64.ExceptionReturn(ELR[], SPSR[]);"
],
"variants": [
{
"pattern": "1 1 0 1 0 1 1 opc#4 op2#5 op3#6 Rt#5 op4#5",
"formats": [
{
"condition": null,
"format": "ERET"
}
],
"decoder": [
"if PSTATE.EL == EL0 then UnallocatedEncoding();"
]
}
],
"name": "ERET",
"description": [
"Exception Return"
]
}
{
"operation": [
"case op of",
" when SystemHintOp_YIELD",
" Hint_Yield();",
"",
" when SystemHintOp_WFE",
" if IsEventRegisterSet() then",
" ClearEventRegister();",
" else",
" if PSTATE.EL == EL0 then",
" // Check for traps described by the OS which may be EL1 or EL2.",
" AArch64.CheckForWFxTrap(EL1, TRUE);",
" if HaveEL(EL2) && !IsSecure() && PSTATE.EL IN {EL0,EL1} && !IsInHost() then",
" // Check for traps described by the Hypervisor.",
" AArch64.CheckForWFxTrap(EL2, TRUE);",
" if HaveEL(EL3) && PSTATE.EL != EL3 then",
" // Check for traps described by the Secure Monitor.",
" AArch64.CheckForWFxTrap(EL3, TRUE);",
" WaitForEvent();",
"",
" when SystemHintOp_WFI",
" if !InterruptPending() then",
" if PSTATE.EL == EL0 then",
" // Check for traps described by the OS which may be EL1 or EL2.",
" AArch64.CheckForWFxTrap(EL1, FALSE);",
" if HaveEL(EL2) && !IsSecure() && PSTATE.EL IN {EL0,EL1} && !IsInHost() then",
" // Check for traps described by the Hypervisor.",
" AArch64.CheckForWFxTrap(EL2, FALSE);",
" if HaveEL(EL3) && PSTATE.EL != EL3 then",
" // Check for traps described by the Secure Monitor.",
" AArch64.CheckForWFxTrap(EL3, FALSE);",
" WaitForInterrupt();",
"",
" when SystemHintOp_SEV",
" SendEvent();",
"",
" when SystemHintOp_SEVL",
" SendEventLocal();",
"",
" when SystemHintOp_ESB",
" ErrorSynchronizationBarrier(MBReqDomain_FullSystem, MBReqTypes_All);",
" AArch64.ESBOperation();",
" if HaveEL(EL2) && !IsSecure() && PSTATE.EL IN {EL0,EL1} then AArch64.vESBOperation();",
" TakeUnmaskedSErrorInterrupts();",
"",
" when SystemHintOp_PSB",
" ProfilingSynchronizationBarrier();",
"",
" otherwise // do nothing"
],
"variants": [
{
"pattern": "1 1 0 1 0 1 0 1 0 0 L#1 op0#2 op1#3 CRn#4 CRm#4 op2#3 Rt#5",
"formats": [
{
"condition": null,
"format": "ESB"
}
],
"decoder": [
"SystemHintOp op;",
"",
"case CRm:op2 of",
" when '0000 000' op = SystemHintOp_NOP;",
" when '0000 001' op = SystemHintOp_YIELD;",
" when '0000 010' op = SystemHintOp_WFE;",
" when '0000 011' op = SystemHintOp_WFI;",
" when '0000 100' op = SystemHintOp_SEV;",
" when '0000 101' op = SystemHintOp_SEVL;",
" when '0010 000' ",
" op = if HaveRASExt() then SystemHintOp_ESB else SystemHintOp_NOP;",
" when '0010 001'",
" op = if HaveStatisticalProfiling() then SystemHintOp_PSB else SystemHintOp_NOP;",
" otherwise op = SystemHintOp_NOP;"
]
}
],
"name": "ESB",
"description": [
"Error Synchronization Barrier"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) hi = V[m];",
"bits(datasize) lo = V[n];",
"bits(datasize*2) concat = hi : lo;",
"",
"V[d] = concat;"
],
"variants": [
{
"pattern": "0 Q#1 1 0 1 1 1 0 op2#2 0 Rm#5 0 imm4#4 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "EXT <Vd>.<T>, <Vn>.<T>, <Vm>.<T>, #<index>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"",
"if Q == '0' && imm4<3> == '1' then UnallocatedEncoding();",
"",
"integer datasize = if Q == '1' then 128 else 64;",
"integer position = UInt(imm4) << 3;"
]
}
],
"name": "EXT",
"description": [
"Extract vector from pair of vectors"
]
}
{
"operation": [
"bits(datasize) result;",
"bits(datasize) operand1 = X[n];",
"bits(datasize) operand2 = X[m];",
"bits(2*datasize) concat = operand1:operand2;",
"",
"result = concat;",
"",
"X[d] = result;"
],
"variants": [
{
"pattern": "sf#1 op21#2 1 0 0 1 1 1 N#1 o0#1 Rm#5 imms#6 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0 && N == 0 && imms == 0xxxxx",
"format": "EXTR <Wd>, <Wn>, <Wm>, #<lsb>"
},
{
"condition": "sf == 1 && N == 1",
"format": "EXTR <Xd>, <Xn>, <Xm>, #<lsb>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer datasize = if sf == '1' then 64 else 32;",
"integer lsb;",
"",
"if N != sf then UnallocatedEncoding();",
"if sf == '0' && imms<5> == '1' then ReservedValue();",
"lsb = UInt(imms);"
]
}
],
"name": "EXTR",
"description": [
"Extract register"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"bits(datasize) result;",
"bits(esize) element1;",
"bits(esize) element2;",
"bits(esize) diff;",
"",
"for e = 0 to elements-1",
" element1 = Elem[operand1, e, esize];",
" element2 = Elem[operand2, e, esize];",
" diff = FPSub(element1, element2, FPCR);",
" Elem[result, e, esize] = if abs then FPAbs(diff) else diff;",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 0 a#1 1 0 Rm#5 0 0 opcode#3 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FABD <Hd>, <Hn>, <Hm>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 16;",
"integer datasize = esize;",
"integer elements = 1;",
"boolean abs = TRUE;"
]
},
{
"pattern": "0 1 U#1 1 1 1 1 0 1 sz#1 1 Rm#5 opcode#5 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FABD <V><d>, <V><n>, <V><m>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 32 << UInt(sz);",
"integer datasize = esize;",
"integer elements = 1;",
"boolean abs = TRUE;"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 a#1 1 0 Rm#5 0 0 opcode#3 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FABD <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"boolean abs = (U == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 1 sz#1 1 Rm#5 opcode#5 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FABD <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"boolean abs = (U == '1');"
]
}
],
"name": "FABD",
"description": [
"Floating-point Absolute Difference (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"bits(datasize) result;",
"bits(esize) element;",
"",
"for e = 0 to elements-1",
" element = Elem[operand, e, esize];",
" if neg then",
" element = FPNeg(element);",
" else",
" element = FPAbs(element);",
" Elem[result, e, esize] = element;",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 a#1 1 1 1 1 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FABS <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"boolean neg = (U == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 1 sz#1 1 0 0 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FABS <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"boolean neg = (U == '1');"
]
}
],
"name": "FABS (vector)",
"description": [
"Floating-point Absolute value (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"",
"bits(datasize) result;",
"bits(datasize) operand = V[n];",
"",
"case fpop of",
" when FPUnaryOp_MOV result = operand;",
" when FPUnaryOp_ABS result = FPAbs(operand);",
" when FPUnaryOp_NEG result = FPNeg(operand);",
" when FPUnaryOp_SQRT result = FPSqrt(operand, FPCR);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "M#1 0 S#1 1 1 1 1 0 type#2 1 0 0 0 0 opc#2 1 0 0 0 0 Rn#5 Rd#5",
"formats": [
{
"condition": "type == 11",
"format": "FABS <Hd>, <Hn>"
},
{
"condition": "type == 00",
"format": "FABS <Sd>, <Sn>"
},
{
"condition": "type == 01",
"format": "FABS <Dd>, <Dn>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer datasize;",
"case type of",
" when '00' datasize = 32;",
" when '01' datasize = 64;",
" when '10' UnallocatedEncoding();",
" when '11'",
" if HaveFP16Ext() then",
" datasize = 16;",
" else",
" UnallocatedEncoding();",
"",
"FPUnaryOp fpop;",
"case opc of",
" when '00' fpop = FPUnaryOp_MOV;",
" when '01' fpop = FPUnaryOp_ABS;",
" when '10' fpop = FPUnaryOp_NEG;",
" when '11' fpop = FPUnaryOp_SQRT;"
]
}
],
"name": "FABS (scalar)",
"description": [
"Floating-point Absolute value (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"bits(datasize) result;",
"bits(esize) element1;",
"bits(esize) element2;",
"boolean test_passed;",
"",
"for e = 0 to elements-1",
" element1 = Elem[operand1, e, esize];",
" element2 = Elem[operand2, e, esize];",
" if abs then",
" element1 = FPAbs(element1);",
" element2 = FPAbs(element2);",
" case cmp of",
" when CompareOp_EQ test_passed = FPCompareEQ(element1, element2, FPCR);",
" when CompareOp_GE test_passed = FPCompareGE(element1, element2, FPCR);",
" when CompareOp_GT test_passed = FPCompareGT(element1, element2, FPCR);",
" Elem[result, e, esize] = if test_passed then Ones() else Zeros();",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 0 E#1 1 0 Rm#5 0 0 1 0 ac#1 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FACGE <Hd>, <Hn>, <Hm>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 16;",
"integer datasize = esize;",
"integer elements = 1;",
"CompareOp cmp;",
"boolean abs;",
"",
"case E:U:ac of",
" when '000' cmp = CompareOp_EQ; abs = FALSE;",
" when '010' cmp = CompareOp_GE; abs = FALSE;",
" when '011' cmp = CompareOp_GE; abs = TRUE;",
" when '110' cmp = CompareOp_GT; abs = FALSE;",
" when '111' cmp = CompareOp_GT; abs = TRUE;",
" otherwise UnallocatedEncoding();"
]
},
{
"pattern": "0 1 U#1 1 1 1 1 0 E#1 sz#1 1 Rm#5 1 1 1 0 ac#1 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FACGE <V><d>, <V><n>, <V><m>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 32 << UInt(sz);",
"integer datasize = esize;",
"integer elements = 1;",
"CompareOp cmp;",
"boolean abs;",
"",
"case E:U:ac of",
" when '000' cmp = CompareOp_EQ; abs = FALSE;",
" when '010' cmp = CompareOp_GE; abs = FALSE;",
" when '011' cmp = CompareOp_GE; abs = TRUE;",
" when '110' cmp = CompareOp_GT; abs = FALSE;",
" when '111' cmp = CompareOp_GT; abs = TRUE;",
" otherwise UnallocatedEncoding();"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 E#1 1 0 Rm#5 0 0 1 0 ac#1 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FACGE <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"CompareOp cmp;",
"boolean abs;",
"",
"case E:U:ac of",
" when '000' cmp = CompareOp_EQ; abs = FALSE;",
" when '010' cmp = CompareOp_GE; abs = FALSE;",
" when '011' cmp = CompareOp_GE; abs = TRUE;",
" when '110' cmp = CompareOp_GT; abs = FALSE;",
" when '111' cmp = CompareOp_GT; abs = TRUE;",
" otherwise UnallocatedEncoding();"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 E#1 sz#1 1 Rm#5 1 1 1 0 ac#1 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FACGE <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"CompareOp cmp;",
"boolean abs;",
"",
"case E:U:ac of",
" when '000' cmp = CompareOp_EQ; abs = FALSE;",
" when '010' cmp = CompareOp_GE; abs = FALSE;",
" when '011' cmp = CompareOp_GE; abs = TRUE;",
" when '110' cmp = CompareOp_GT; abs = FALSE;",
" when '111' cmp = CompareOp_GT; abs = TRUE;",
" otherwise UnallocatedEncoding();"
]
}
],
"name": "FACGE",
"description": [
"Floating-point Absolute Compare Greater than or Equal (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"bits(datasize) result;",
"bits(esize) element1;",
"bits(esize) element2;",
"boolean test_passed;",
"",
"for e = 0 to elements-1",
" element1 = Elem[operand1, e, esize];",
" element2 = Elem[operand2, e, esize];",
" if abs then",
" element1 = FPAbs(element1);",
" element2 = FPAbs(element2);",
" case cmp of",
" when CompareOp_EQ test_passed = FPCompareEQ(element1, element2, FPCR);",
" when CompareOp_GE test_passed = FPCompareGE(element1, element2, FPCR);",
" when CompareOp_GT test_passed = FPCompareGT(element1, element2, FPCR);",
" Elem[result, e, esize] = if test_passed then Ones() else Zeros();",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 0 E#1 1 0 Rm#5 0 0 1 0 ac#1 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FACGT <Hd>, <Hn>, <Hm>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 16;",
"integer datasize = esize;",
"integer elements = 1;",
"CompareOp cmp;",
"boolean abs;",
"",
"case E:U:ac of",
" when '000' cmp = CompareOp_EQ; abs = FALSE;",
" when '010' cmp = CompareOp_GE; abs = FALSE;",
" when '011' cmp = CompareOp_GE; abs = TRUE;",
" when '110' cmp = CompareOp_GT; abs = FALSE;",
" when '111' cmp = CompareOp_GT; abs = TRUE;",
" otherwise UnallocatedEncoding();"
]
},
{
"pattern": "0 1 U#1 1 1 1 1 0 E#1 sz#1 1 Rm#5 1 1 1 0 ac#1 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FACGT <V><d>, <V><n>, <V><m>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 32 << UInt(sz);",
"integer datasize = esize;",
"integer elements = 1;",
"CompareOp cmp;",
"boolean abs;",
"",
"case E:U:ac of",
" when '000' cmp = CompareOp_EQ; abs = FALSE;",
" when '010' cmp = CompareOp_GE; abs = FALSE;",
" when '011' cmp = CompareOp_GE; abs = TRUE;",
" when '110' cmp = CompareOp_GT; abs = FALSE;",
" when '111' cmp = CompareOp_GT; abs = TRUE;",
" otherwise UnallocatedEncoding();"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 E#1 1 0 Rm#5 0 0 1 0 ac#1 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FACGT <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"CompareOp cmp;",
"boolean abs;",
"",
"case E:U:ac of",
" when '000' cmp = CompareOp_EQ; abs = FALSE;",
" when '010' cmp = CompareOp_GE; abs = FALSE;",
" when '011' cmp = CompareOp_GE; abs = TRUE;",
" when '110' cmp = CompareOp_GT; abs = FALSE;",
" when '111' cmp = CompareOp_GT; abs = TRUE;",
" otherwise UnallocatedEncoding();"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 E#1 sz#1 1 Rm#5 1 1 1 0 ac#1 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FACGT <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"CompareOp cmp;",
"boolean abs;",
"",
"case E:U:ac of",
" when '000' cmp = CompareOp_EQ; abs = FALSE;",
" when '010' cmp = CompareOp_GE; abs = FALSE;",
" when '011' cmp = CompareOp_GE; abs = TRUE;",
" when '110' cmp = CompareOp_GT; abs = FALSE;",
" when '111' cmp = CompareOp_GT; abs = TRUE;",
" otherwise UnallocatedEncoding();"
]
}
],
"name": "FACGT",
"description": [
"Floating-point Absolute Compare Greater than (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"bits(datasize) result;",
"bits(2*datasize) concat = operand2:operand1;",
"bits(esize) element1;",
"bits(esize) element2;",
"",
"for e = 0 to elements-1",
" if pair then",
" element1 = Elem[concat, 2*e, esize];",
" element2 = Elem[concat, (2*e)+1, esize];",
" else",
" element1 = Elem[operand1, e, esize];",
" element2 = Elem[operand2, e, esize];",
" Elem[result, e, esize] = FPAdd(element1, element2, FPCR);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 a#1 1 0 Rm#5 0 0 opcode#3 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FADD <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"boolean pair = (U == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 0 sz#1 1 Rm#5 opcode#5 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FADD <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"boolean pair = (U == '1');"
]
}
],
"name": "FADD (vector)",
"description": [
"Floating-point Add (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) result;",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"",
"if sub_op then",
" result = FPSub(operand1, operand2, FPCR);",
"else",
" result = FPAdd(operand1, operand2, FPCR);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "M#1 0 S#1 1 1 1 1 0 type#2 1 Rm#5 0 0 1 op#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": "type == 11",
"format": "FADD <Hd>, <Hn>, <Hm>"
},
{
"condition": "type == 00",
"format": "FADD <Sd>, <Sn>, <Sm>"
},
{
"condition": "type == 01",
"format": "FADD <Dd>, <Dn>, <Dm>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"",
"integer datasize;",
"case type of",
" when '00' datasize = 32;",
" when '01' datasize = 64;",
" when '10' UnallocatedEncoding();",
" when '11'",
" if HaveFP16Ext() then",
" datasize = 16;",
" else",
" UnallocatedEncoding();",
"",
"boolean sub_op = (op == '1');"
]
}
],
"name": "FADD (scalar)",
"description": [
"Floating-point Add (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"V[d] = Reduce(op, operand, esize);"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 0 0 sz#1 1 1 0 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FADDP <V><d>, <Vn>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer esize = 16;",
"if sz == '1' then ReservedValue();",
"integer datasize = esize * 2;",
"integer elements = 2;",
"",
"ReduceOp op = ReduceOp_FADD;"
]
},
{
"pattern": "0 1 U#1 1 1 1 1 0 0 sz#1 1 1 0 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FADDP <V><d>, <Vn>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 32 << UInt(sz);",
"integer datasize = esize * 2;",
"integer elements = 2;",
"",
"ReduceOp op = ReduceOp_FADD;"
]
}
],
"name": "FADDP (scalar)",
"description": [
"Floating-point Add Pair of elements (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"bits(datasize) result;",
"bits(2*datasize) concat = operand2:operand1;",
"bits(esize) element1;",
"bits(esize) element2;",
"",
"for e = 0 to elements-1",
" if pair then",
" element1 = Elem[concat, 2*e, esize];",
" element2 = Elem[concat, (2*e)+1, esize];",
" else",
" element1 = Elem[operand1, e, esize];",
" element2 = Elem[operand2, e, esize];",
" Elem[result, e, esize] = FPAdd(element1, element2, FPCR);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 a#1 1 0 Rm#5 0 0 opcode#3 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FADDP <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"boolean pair = (U == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 0 sz#1 1 Rm#5 opcode#5 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FADDP <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"boolean pair = (U == '1');"
]
}
],
"name": "FADDP (vector)",
"description": [
"Floating-point Add Pairwise (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2;",
"",
"operand2 = V[m];",
"",
"if ConditionHolds(condition) then",
" flags = FPCompare(operand1, operand2, signal_all_nans, FPCR);",
"PSTATE. = flags;"
],
"variants": [
{
"pattern": "M#1 0 S#1 1 1 1 1 0 type#2 1 Rm#5 cond#4 0 1 Rn#5 op#1 nzcv#4",
"formats": [
{
"condition": "type == 11",
"format": "FCCMP <Hn>, <Hm>, #<nzcv>, <cond>"
},
{
"condition": "type == 00",
"format": "FCCMP <Sn>, <Sm>, #<nzcv>, <cond>"
},
{
"condition": "type == 01",
"format": "FCCMP <Dn>, <Dm>, #<nzcv>, <cond>"
}
],
"decoder": [
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"",
"integer datasize;",
"case type of",
" when '00' datasize = 32;",
" when '01' datasize = 64;",
" when '10' UnallocatedEncoding();",
" when '11'",
" if HaveFP16Ext() then",
" datasize = 16;",
" else",
" UnallocatedEncoding();",
"",
"boolean signal_all_nans = (op == '1');",
"bits(4) condition = cond;",
"bits(4) flags = nzcv;"
]
}
],
"name": "FCCMP",
"description": [
"Floating-point Conditional quiet Compare (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2;",
"",
"operand2 = V[m];",
"",
"if ConditionHolds(condition) then",
" flags = FPCompare(operand1, operand2, signal_all_nans, FPCR);",
"PSTATE. = flags;"
],
"variants": [
{
"pattern": "M#1 0 S#1 1 1 1 1 0 type#2 1 Rm#5 cond#4 0 1 Rn#5 op#1 nzcv#4",
"formats": [
{
"condition": "type == 11",
"format": "FCCMPE <Hn>, <Hm>, #<nzcv>, <cond>"
},
{
"condition": "type == 00",
"format": "FCCMPE <Sn>, <Sm>, #<nzcv>, <cond>"
},
{
"condition": "type == 01",
"format": "FCCMPE <Dn>, <Dm>, #<nzcv>, <cond>"
}
],
"decoder": [
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"",
"integer datasize;",
"case type of",
" when '00' datasize = 32;",
" when '01' datasize = 64;",
" when '10' UnallocatedEncoding();",
" when '11'",
" if HaveFP16Ext() then",
" datasize = 16;",
" else",
" UnallocatedEncoding();",
"",
"boolean signal_all_nans = (op == '1');",
"bits(4) condition = cond;",
"bits(4) flags = nzcv;"
]
}
],
"name": "FCCMPE",
"description": [
"Floating-point Conditional signaling Compare (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"bits(datasize) result;",
"bits(esize) element1;",
"bits(esize) element2;",
"boolean test_passed;",
"",
"for e = 0 to elements-1",
" element1 = Elem[operand1, e, esize];",
" element2 = Elem[operand2, e, esize];",
" if abs then",
" element1 = FPAbs(element1);",
" element2 = FPAbs(element2);",
" case cmp of",
" when CompareOp_EQ test_passed = FPCompareEQ(element1, element2, FPCR);",
" when CompareOp_GE test_passed = FPCompareGE(element1, element2, FPCR);",
" when CompareOp_GT test_passed = FPCompareGT(element1, element2, FPCR);",
" Elem[result, e, esize] = if test_passed then Ones() else Zeros();",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 0 E#1 1 0 Rm#5 0 0 1 0 ac#1 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCMEQ <Hd>, <Hn>, <Hm>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 16;",
"integer datasize = esize;",
"integer elements = 1;",
"CompareOp cmp;",
"boolean abs;",
"",
"case E:U:ac of",
" when '000' cmp = CompareOp_EQ; abs = FALSE;",
" when '010' cmp = CompareOp_GE; abs = FALSE;",
" when '011' cmp = CompareOp_GE; abs = TRUE;",
" when '110' cmp = CompareOp_GT; abs = FALSE;",
" when '111' cmp = CompareOp_GT; abs = TRUE;",
" otherwise UnallocatedEncoding();"
]
},
{
"pattern": "0 1 U#1 1 1 1 1 0 E#1 sz#1 1 Rm#5 1 1 1 0 ac#1 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCMEQ <V><d>, <V><n>, <V><m>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 32 << UInt(sz);",
"integer datasize = esize;",
"integer elements = 1;",
"CompareOp cmp;",
"boolean abs;",
"",
"case E:U:ac of",
" when '000' cmp = CompareOp_EQ; abs = FALSE;",
" when '010' cmp = CompareOp_GE; abs = FALSE;",
" when '011' cmp = CompareOp_GE; abs = TRUE;",
" when '110' cmp = CompareOp_GT; abs = FALSE;",
" when '111' cmp = CompareOp_GT; abs = TRUE;",
" otherwise UnallocatedEncoding();"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 E#1 1 0 Rm#5 0 0 1 0 ac#1 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCMEQ <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"CompareOp cmp;",
"boolean abs;",
"",
"case E:U:ac of",
" when '000' cmp = CompareOp_EQ; abs = FALSE;",
" when '010' cmp = CompareOp_GE; abs = FALSE;",
" when '011' cmp = CompareOp_GE; abs = TRUE;",
" when '110' cmp = CompareOp_GT; abs = FALSE;",
" when '111' cmp = CompareOp_GT; abs = TRUE;",
" otherwise UnallocatedEncoding();"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 E#1 sz#1 1 Rm#5 1 1 1 0 ac#1 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCMEQ <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"CompareOp cmp;",
"boolean abs;",
"",
"case E:U:ac of",
" when '000' cmp = CompareOp_EQ; abs = FALSE;",
" when '010' cmp = CompareOp_GE; abs = FALSE;",
" when '011' cmp = CompareOp_GE; abs = TRUE;",
" when '110' cmp = CompareOp_GT; abs = FALSE;",
" when '111' cmp = CompareOp_GT; abs = TRUE;",
" otherwise UnallocatedEncoding();"
]
}
],
"name": "FCMEQ (register)",
"description": [
"Floating-point Compare Equal (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"bits(datasize) result;",
"bits(esize) zero = FPZero('0');",
"bits(esize) element;",
"boolean test_passed;",
"",
"for e = 0 to elements-1",
" element = Elem[operand, e, esize];",
" case comparison of",
" when CompareOp_GT test_passed = FPCompareGT(element, zero, FPCR);",
" when CompareOp_GE test_passed = FPCompareGE(element, zero, FPCR);",
" when CompareOp_EQ test_passed = FPCompareEQ(element, zero, FPCR);",
" when CompareOp_LE test_passed = FPCompareGE(zero, element, FPCR);",
" when CompareOp_LT test_passed = FPCompareGT(zero, element, FPCR);",
" Elem[result, e, esize] = if test_passed then Ones() else Zeros();",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 0 a#1 1 1 1 1 0 0 0 1 1 0 op#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCMEQ <Hd>, <Hn>, #0.0"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = esize;",
"integer elements = 1;",
"",
"CompareOp comparison;",
"case op:U of",
" when '00' comparison = CompareOp_GT;",
" when '01' comparison = CompareOp_GE;",
" when '10' comparison = CompareOp_EQ;",
" when '11' comparison = CompareOp_LE;"
]
},
{
"pattern": "0 1 U#1 1 1 1 1 0 1 sz#1 1 0 0 0 0 0 1 1 0 op#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCMEQ <V><d>, <V><n>, #0.0"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 32 << UInt(sz);",
"integer datasize = esize;",
"integer elements = 1;",
"",
"CompareOp comparison;",
"case op:U of",
" when '00' comparison = CompareOp_GT;",
" when '01' comparison = CompareOp_GE;",
" when '10' comparison = CompareOp_EQ;",
" when '11' comparison = CompareOp_LE;"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 a#1 1 1 1 1 0 0 0 1 1 0 op#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCMEQ <Vd>.<T>, <Vn>.<T>, #0.0"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"CompareOp comparison;",
"case op:U of",
" when '00' comparison = CompareOp_GT;",
" when '01' comparison = CompareOp_GE;",
" when '10' comparison = CompareOp_EQ;",
" when '11' comparison = CompareOp_LE;"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 1 sz#1 1 0 0 0 0 0 1 1 0 op#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCMEQ <Vd>.<T>, <Vn>.<T>, #0.0"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"CompareOp comparison;",
"case op:U of",
" when '00' comparison = CompareOp_GT;",
" when '01' comparison = CompareOp_GE;",
" when '10' comparison = CompareOp_EQ;",
" when '11' comparison = CompareOp_LE;"
]
}
],
"name": "FCMEQ (zero)",
"description": [
"Floating-point Compare Equal to zero (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"bits(datasize) result;",
"bits(esize) element1;",
"bits(esize) element2;",
"boolean test_passed;",
"",
"for e = 0 to elements-1",
" element1 = Elem[operand1, e, esize];",
" element2 = Elem[operand2, e, esize];",
" if abs then",
" element1 = FPAbs(element1);",
" element2 = FPAbs(element2);",
" case cmp of",
" when CompareOp_EQ test_passed = FPCompareEQ(element1, element2, FPCR);",
" when CompareOp_GE test_passed = FPCompareGE(element1, element2, FPCR);",
" when CompareOp_GT test_passed = FPCompareGT(element1, element2, FPCR);",
" Elem[result, e, esize] = if test_passed then Ones() else Zeros();",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 0 E#1 1 0 Rm#5 0 0 1 0 ac#1 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCMGE <Hd>, <Hn>, <Hm>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 16;",
"integer datasize = esize;",
"integer elements = 1;",
"CompareOp cmp;",
"boolean abs;",
"",
"case E:U:ac of",
" when '000' cmp = CompareOp_EQ; abs = FALSE;",
" when '010' cmp = CompareOp_GE; abs = FALSE;",
" when '011' cmp = CompareOp_GE; abs = TRUE;",
" when '110' cmp = CompareOp_GT; abs = FALSE;",
" when '111' cmp = CompareOp_GT; abs = TRUE;",
" otherwise UnallocatedEncoding();"
]
},
{
"pattern": "0 1 U#1 1 1 1 1 0 E#1 sz#1 1 Rm#5 1 1 1 0 ac#1 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCMGE <V><d>, <V><n>, <V><m>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 32 << UInt(sz);",
"integer datasize = esize;",
"integer elements = 1;",
"CompareOp cmp;",
"boolean abs;",
"",
"case E:U:ac of",
" when '000' cmp = CompareOp_EQ; abs = FALSE;",
" when '010' cmp = CompareOp_GE; abs = FALSE;",
" when '011' cmp = CompareOp_GE; abs = TRUE;",
" when '110' cmp = CompareOp_GT; abs = FALSE;",
" when '111' cmp = CompareOp_GT; abs = TRUE;",
" otherwise UnallocatedEncoding();"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 E#1 1 0 Rm#5 0 0 1 0 ac#1 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCMGE <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"CompareOp cmp;",
"boolean abs;",
"",
"case E:U:ac of",
" when '000' cmp = CompareOp_EQ; abs = FALSE;",
" when '010' cmp = CompareOp_GE; abs = FALSE;",
" when '011' cmp = CompareOp_GE; abs = TRUE;",
" when '110' cmp = CompareOp_GT; abs = FALSE;",
" when '111' cmp = CompareOp_GT; abs = TRUE;",
" otherwise UnallocatedEncoding();"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 E#1 sz#1 1 Rm#5 1 1 1 0 ac#1 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCMGE <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"CompareOp cmp;",
"boolean abs;",
"",
"case E:U:ac of",
" when '000' cmp = CompareOp_EQ; abs = FALSE;",
" when '010' cmp = CompareOp_GE; abs = FALSE;",
" when '011' cmp = CompareOp_GE; abs = TRUE;",
" when '110' cmp = CompareOp_GT; abs = FALSE;",
" when '111' cmp = CompareOp_GT; abs = TRUE;",
" otherwise UnallocatedEncoding();"
]
}
],
"name": "FCMGE (register)",
"description": [
"Floating-point Compare Greater than or Equal (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"bits(datasize) result;",
"bits(esize) zero = FPZero('0');",
"bits(esize) element;",
"boolean test_passed;",
"",
"for e = 0 to elements-1",
" element = Elem[operand, e, esize];",
" case comparison of",
" when CompareOp_GT test_passed = FPCompareGT(element, zero, FPCR);",
" when CompareOp_GE test_passed = FPCompareGE(element, zero, FPCR);",
" when CompareOp_EQ test_passed = FPCompareEQ(element, zero, FPCR);",
" when CompareOp_LE test_passed = FPCompareGE(zero, element, FPCR);",
" when CompareOp_LT test_passed = FPCompareGT(zero, element, FPCR);",
" Elem[result, e, esize] = if test_passed then Ones() else Zeros();",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 0 a#1 1 1 1 1 0 0 0 1 1 0 op#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCMGE <Hd>, <Hn>, #0.0"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = esize;",
"integer elements = 1;",
"",
"CompareOp comparison;",
"case op:U of",
" when '00' comparison = CompareOp_GT;",
" when '01' comparison = CompareOp_GE;",
" when '10' comparison = CompareOp_EQ;",
" when '11' comparison = CompareOp_LE;"
]
},
{
"pattern": "0 1 U#1 1 1 1 1 0 1 sz#1 1 0 0 0 0 0 1 1 0 op#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCMGE <V><d>, <V><n>, #0.0"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 32 << UInt(sz);",
"integer datasize = esize;",
"integer elements = 1;",
"",
"CompareOp comparison;",
"case op:U of",
" when '00' comparison = CompareOp_GT;",
" when '01' comparison = CompareOp_GE;",
" when '10' comparison = CompareOp_EQ;",
" when '11' comparison = CompareOp_LE;"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 a#1 1 1 1 1 0 0 0 1 1 0 op#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCMGE <Vd>.<T>, <Vn>.<T>, #0.0"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"CompareOp comparison;",
"case op:U of",
" when '00' comparison = CompareOp_GT;",
" when '01' comparison = CompareOp_GE;",
" when '10' comparison = CompareOp_EQ;",
" when '11' comparison = CompareOp_LE;"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 1 sz#1 1 0 0 0 0 0 1 1 0 op#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCMGE <Vd>.<T>, <Vn>.<T>, #0.0"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"CompareOp comparison;",
"case op:U of",
" when '00' comparison = CompareOp_GT;",
" when '01' comparison = CompareOp_GE;",
" when '10' comparison = CompareOp_EQ;",
" when '11' comparison = CompareOp_LE;"
]
}
],
"name": "FCMGE (zero)",
"description": [
"Floating-point Compare Greater than or Equal to zero (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"bits(datasize) result;",
"bits(esize) element1;",
"bits(esize) element2;",
"boolean test_passed;",
"",
"for e = 0 to elements-1",
" element1 = Elem[operand1, e, esize];",
" element2 = Elem[operand2, e, esize];",
" if abs then",
" element1 = FPAbs(element1);",
" element2 = FPAbs(element2);",
" case cmp of",
" when CompareOp_EQ test_passed = FPCompareEQ(element1, element2, FPCR);",
" when CompareOp_GE test_passed = FPCompareGE(element1, element2, FPCR);",
" when CompareOp_GT test_passed = FPCompareGT(element1, element2, FPCR);",
" Elem[result, e, esize] = if test_passed then Ones() else Zeros();",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 0 E#1 1 0 Rm#5 0 0 1 0 ac#1 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCMGT <Hd>, <Hn>, <Hm>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 16;",
"integer datasize = esize;",
"integer elements = 1;",
"CompareOp cmp;",
"boolean abs;",
"",
"case E:U:ac of",
" when '000' cmp = CompareOp_EQ; abs = FALSE;",
" when '010' cmp = CompareOp_GE; abs = FALSE;",
" when '011' cmp = CompareOp_GE; abs = TRUE;",
" when '110' cmp = CompareOp_GT; abs = FALSE;",
" when '111' cmp = CompareOp_GT; abs = TRUE;",
" otherwise UnallocatedEncoding();"
]
},
{
"pattern": "0 1 U#1 1 1 1 1 0 E#1 sz#1 1 Rm#5 1 1 1 0 ac#1 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCMGT <V><d>, <V><n>, <V><m>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 32 << UInt(sz);",
"integer datasize = esize;",
"integer elements = 1;",
"CompareOp cmp;",
"boolean abs;",
"",
"case E:U:ac of",
" when '000' cmp = CompareOp_EQ; abs = FALSE;",
" when '010' cmp = CompareOp_GE; abs = FALSE;",
" when '011' cmp = CompareOp_GE; abs = TRUE;",
" when '110' cmp = CompareOp_GT; abs = FALSE;",
" when '111' cmp = CompareOp_GT; abs = TRUE;",
" otherwise UnallocatedEncoding();"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 E#1 1 0 Rm#5 0 0 1 0 ac#1 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCMGT <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"CompareOp cmp;",
"boolean abs;",
"",
"case E:U:ac of",
" when '000' cmp = CompareOp_EQ; abs = FALSE;",
" when '010' cmp = CompareOp_GE; abs = FALSE;",
" when '011' cmp = CompareOp_GE; abs = TRUE;",
" when '110' cmp = CompareOp_GT; abs = FALSE;",
" when '111' cmp = CompareOp_GT; abs = TRUE;",
" otherwise UnallocatedEncoding();"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 E#1 sz#1 1 Rm#5 1 1 1 0 ac#1 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCMGT <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"CompareOp cmp;",
"boolean abs;",
"",
"case E:U:ac of",
" when '000' cmp = CompareOp_EQ; abs = FALSE;",
" when '010' cmp = CompareOp_GE; abs = FALSE;",
" when '011' cmp = CompareOp_GE; abs = TRUE;",
" when '110' cmp = CompareOp_GT; abs = FALSE;",
" when '111' cmp = CompareOp_GT; abs = TRUE;",
" otherwise UnallocatedEncoding();"
]
}
],
"name": "FCMGT (register)",
"description": [
"Floating-point Compare Greater than (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"bits(datasize) result;",
"bits(esize) zero = FPZero('0');",
"bits(esize) element;",
"boolean test_passed;",
"",
"for e = 0 to elements-1",
" element = Elem[operand, e, esize];",
" case comparison of",
" when CompareOp_GT test_passed = FPCompareGT(element, zero, FPCR);",
" when CompareOp_GE test_passed = FPCompareGE(element, zero, FPCR);",
" when CompareOp_EQ test_passed = FPCompareEQ(element, zero, FPCR);",
" when CompareOp_LE test_passed = FPCompareGE(zero, element, FPCR);",
" when CompareOp_LT test_passed = FPCompareGT(zero, element, FPCR);",
" Elem[result, e, esize] = if test_passed then Ones() else Zeros();",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 0 a#1 1 1 1 1 0 0 0 1 1 0 op#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCMGT <Hd>, <Hn>, #0.0"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = esize;",
"integer elements = 1;",
"",
"CompareOp comparison;",
"case op:U of",
" when '00' comparison = CompareOp_GT;",
" when '01' comparison = CompareOp_GE;",
" when '10' comparison = CompareOp_EQ;",
" when '11' comparison = CompareOp_LE;"
]
},
{
"pattern": "0 1 U#1 1 1 1 1 0 1 sz#1 1 0 0 0 0 0 1 1 0 op#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCMGT <V><d>, <V><n>, #0.0"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 32 << UInt(sz);",
"integer datasize = esize;",
"integer elements = 1;",
"",
"CompareOp comparison;",
"case op:U of",
" when '00' comparison = CompareOp_GT;",
" when '01' comparison = CompareOp_GE;",
" when '10' comparison = CompareOp_EQ;",
" when '11' comparison = CompareOp_LE;"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 a#1 1 1 1 1 0 0 0 1 1 0 op#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCMGT <Vd>.<T>, <Vn>.<T>, #0.0"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"CompareOp comparison;",
"case op:U of",
" when '00' comparison = CompareOp_GT;",
" when '01' comparison = CompareOp_GE;",
" when '10' comparison = CompareOp_EQ;",
" when '11' comparison = CompareOp_LE;"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 1 sz#1 1 0 0 0 0 0 1 1 0 op#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCMGT <Vd>.<T>, <Vn>.<T>, #0.0"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"CompareOp comparison;",
"case op:U of",
" when '00' comparison = CompareOp_GT;",
" when '01' comparison = CompareOp_GE;",
" when '10' comparison = CompareOp_EQ;",
" when '11' comparison = CompareOp_LE;"
]
}
],
"name": "FCMGT (zero)",
"description": [
"Floating-point Compare Greater than zero (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"bits(datasize) result;",
"bits(esize) zero = FPZero('0');",
"bits(esize) element;",
"boolean test_passed;",
"",
"for e = 0 to elements-1",
" element = Elem[operand, e, esize];",
" case comparison of",
" when CompareOp_GT test_passed = FPCompareGT(element, zero, FPCR);",
" when CompareOp_GE test_passed = FPCompareGE(element, zero, FPCR);",
" when CompareOp_EQ test_passed = FPCompareEQ(element, zero, FPCR);",
" when CompareOp_LE test_passed = FPCompareGE(zero, element, FPCR);",
" when CompareOp_LT test_passed = FPCompareGT(zero, element, FPCR);",
" Elem[result, e, esize] = if test_passed then Ones() else Zeros();",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 0 a#1 1 1 1 1 0 0 0 1 1 0 op#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCMLE <Hd>, <Hn>, #0.0"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = esize;",
"integer elements = 1;",
"",
"CompareOp comparison;",
"case op:U of",
" when '00' comparison = CompareOp_GT;",
" when '01' comparison = CompareOp_GE;",
" when '10' comparison = CompareOp_EQ;",
" when '11' comparison = CompareOp_LE;"
]
},
{
"pattern": "0 1 U#1 1 1 1 1 0 1 sz#1 1 0 0 0 0 0 1 1 0 op#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCMLE <V><d>, <V><n>, #0.0"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 32 << UInt(sz);",
"integer datasize = esize;",
"integer elements = 1;",
"",
"CompareOp comparison;",
"case op:U of",
" when '00' comparison = CompareOp_GT;",
" when '01' comparison = CompareOp_GE;",
" when '10' comparison = CompareOp_EQ;",
" when '11' comparison = CompareOp_LE;"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 a#1 1 1 1 1 0 0 0 1 1 0 op#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCMLE <Vd>.<T>, <Vn>.<T>, #0.0"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"CompareOp comparison;",
"case op:U of",
" when '00' comparison = CompareOp_GT;",
" when '01' comparison = CompareOp_GE;",
" when '10' comparison = CompareOp_EQ;",
" when '11' comparison = CompareOp_LE;"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 1 sz#1 1 0 0 0 0 0 1 1 0 op#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCMLE <Vd>.<T>, <Vn>.<T>, #0.0"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"CompareOp comparison;",
"case op:U of",
" when '00' comparison = CompareOp_GT;",
" when '01' comparison = CompareOp_GE;",
" when '10' comparison = CompareOp_EQ;",
" when '11' comparison = CompareOp_LE;"
]
}
],
"name": "FCMLE (zero)",
"description": [
"Floating-point Compare Less than or Equal to zero (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"bits(datasize) result;",
"bits(esize) zero = FPZero('0');",
"bits(esize) element;",
"boolean test_passed;",
"",
"for e = 0 to elements-1",
" element = Elem[operand, e, esize];",
" case comparison of",
" when CompareOp_GT test_passed = FPCompareGT(element, zero, FPCR);",
" when CompareOp_GE test_passed = FPCompareGE(element, zero, FPCR);",
" when CompareOp_EQ test_passed = FPCompareEQ(element, zero, FPCR);",
" when CompareOp_LE test_passed = FPCompareGE(zero, element, FPCR);",
" when CompareOp_LT test_passed = FPCompareGT(zero, element, FPCR);",
" Elem[result, e, esize] = if test_passed then Ones() else Zeros();",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 0 a#1 1 1 1 1 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCMLT <Hd>, <Hn>, #0.0"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = esize;",
"integer elements = 1;",
"",
"CompareOp comparison = CompareOp_LT;"
]
},
{
"pattern": "0 1 U#1 1 1 1 1 0 1 sz#1 1 0 0 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCMLT <V><d>, <V><n>, #0.0"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 32 << UInt(sz);",
"integer datasize = esize;",
"integer elements = 1;",
"",
"CompareOp comparison = CompareOp_LT;"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 a#1 1 1 1 1 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCMLT <Vd>.<T>, <Vn>.<T>, #0.0"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"CompareOp comparison = CompareOp_LT;"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 1 sz#1 1 0 0 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCMLT <Vd>.<T>, <Vn>.<T>, #0.0"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"CompareOp comparison = CompareOp_LT;"
]
}
],
"name": "FCMLT (zero)",
"description": [
"Floating-point Compare Less than zero (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2;",
"",
"operand2 = if cmp_with_zero then FPZero('0') else V[m];",
"",
"PSTATE. = FPCompare(operand1, operand2, signal_all_nans, FPCR);"
],
"variants": [
{
"pattern": "M#1 0 S#1 1 1 1 1 0 type#2 1 Rm#5 op#2 1 0 0 0 Rn#5 opc#2 0 0 0",
"formats": [
{
"condition": "type == 11 && opc == 00",
"format": "FCMP <Hn>, <Hm>"
},
{
"condition": "type == 11 && Rm == (00000) && opc == 01",
"format": "FCMP <Hn>, #0.0"
},
{
"condition": "type == 00 && opc == 00",
"format": "FCMP <Sn>, <Sm>"
},
{
"condition": "type == 00 && Rm == (00000) && opc == 01",
"format": "FCMP <Sn>, #0.0"
},
{
"condition": "type == 01 && opc == 00",
"format": "FCMP <Dn>, <Dm>"
},
{
"condition": "type == 01 && Rm == (00000) && opc == 01",
"format": "FCMP <Dn>, #0.0"
}
],
"decoder": [
"integer n = UInt(Rn);",
"integer m = UInt(Rm); // ignored when opc<0> == '1'",
"",
"integer datasize;",
"case type of",
" when '00' datasize = 32;",
" when '01' datasize = 64;",
" when '10' UnallocatedEncoding();",
" when '11'",
" if HaveFP16Ext() then",
" datasize = 16;",
" else",
" UnallocatedEncoding();",
"",
"boolean signal_all_nans = (opc<1> == '1');",
"boolean cmp_with_zero = (opc<0> == '1');"
]
}
],
"name": "FCMP",
"description": [
"Floating-point quiet Compare (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2;",
"",
"operand2 = if cmp_with_zero then FPZero('0') else V[m];",
"",
"PSTATE. = FPCompare(operand1, operand2, signal_all_nans, FPCR);"
],
"variants": [
{
"pattern": "M#1 0 S#1 1 1 1 1 0 type#2 1 Rm#5 op#2 1 0 0 0 Rn#5 opc#2 0 0 0",
"formats": [
{
"condition": "type == 11 && opc == 10",
"format": "FCMPE <Hn>, <Hm>"
},
{
"condition": "type == 11 && Rm == (00000) && opc == 11",
"format": "FCMPE <Hn>, #0.0"
},
{
"condition": "type == 00 && opc == 10",
"format": "FCMPE <Sn>, <Sm>"
},
{
"condition": "type == 00 && Rm == (00000) && opc == 11",
"format": "FCMPE <Sn>, #0.0"
},
{
"condition": "type == 01 && opc == 10",
"format": "FCMPE <Dn>, <Dm>"
},
{
"condition": "type == 01 && Rm == (00000) && opc == 11",
"format": "FCMPE <Dn>, #0.0"
}
],
"decoder": [
"integer n = UInt(Rn);",
"integer m = UInt(Rm); // ignored when opc<0> == '1'",
"",
"integer datasize;",
"case type of",
" when '00' datasize = 32;",
" when '01' datasize = 64;",
" when '10' UnallocatedEncoding();",
" when '11'",
" if HaveFP16Ext() then",
" datasize = 16;",
" else",
" UnallocatedEncoding();",
"",
"boolean signal_all_nans = (opc<1> == '1');",
"boolean cmp_with_zero = (opc<0> == '1');"
]
}
],
"name": "FCMPE",
"description": [
"Floating-point signaling Compare (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) result;",
"",
"result = if ConditionHolds(condition) then V[n] else V[m];",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "M#1 0 S#1 1 1 1 1 0 type#2 1 Rm#5 cond#4 1 1 Rn#5 Rd#5",
"formats": [
{
"condition": "type == 11",
"format": "FCSEL <Hd>, <Hn>, <Hm>, <cond>"
},
{
"condition": "type == 00",
"format": "FCSEL <Sd>, <Sn>, <Sm>, <cond>"
},
{
"condition": "type == 01",
"format": "FCSEL <Dd>, <Dn>, <Dm>, <cond>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"",
"integer datasize;",
"case type of",
" when '00' datasize = 32;",
" when '01' datasize = 64;",
" when '10' UnallocatedEncoding();",
" when '11'",
" if HaveFP16Ext() then",
" datasize = 16;",
" else",
" UnallocatedEncoding();",
"",
"bits(4) condition = cond;"
]
}
],
"name": "FCSEL",
"description": [
"Floating-point Conditional Select (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"",
"bits(dstsize) result;",
"bits(srcsize) operand = V[n];",
"",
"result = FPConvert(operand, FPCR);",
"V[d] = result;"
],
"variants": [
{
"pattern": "M#1 0 S#1 1 1 1 1 0 type#2 1 0 0 0 1 opc#2 1 0 0 0 0 Rn#5 Rd#5",
"formats": [
{
"condition": "type == 11 && opc == 00",
"format": "FCVT <Sd>, <Hn>"
},
{
"condition": "type == 11 && opc == 01",
"format": "FCVT <Dd>, <Hn>"
},
{
"condition": "type == 00 && opc == 11",
"format": "FCVT <Hd>, <Sn>"
},
{
"condition": "type == 00 && opc == 01",
"format": "FCVT <Dd>, <Sn>"
},
{
"condition": "type == 01 && opc == 11",
"format": "FCVT <Hd>, <Dn>"
},
{
"condition": "type == 01 && opc == 00",
"format": "FCVT <Sd>, <Dn>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if type == opc then UnallocatedEncoding();",
"",
"integer srcsize;",
"case type of",
" when '00' srcsize = 32;",
" when '01' srcsize = 64;",
" when '10' UnallocatedEncoding();",
" when '11' srcsize = 16;",
"integer dstsize;",
"case opc of",
" when '00' dstsize = 32;",
" when '01' dstsize = 64;",
" when '10' UnallocatedEncoding();",
" when '11' dstsize = 16;"
]
}
],
"name": "FCVT",
"description": [
"Floating-point Convert precision (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"bits(datasize) result;",
"bits(esize) element;",
"",
"for e = 0 to elements-1",
" element = Elem[operand, e, esize];",
" Elem[result, e, esize] = FPToFixed(element, 0, unsigned, FPCR, rounding);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 0 size<1>#1 1 1 1 1 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTAS <Hd>, <Hn>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = esize;",
"integer elements = 1;",
"",
"FPRounding rounding = FPRounding_TIEAWAY;",
"boolean unsigned = (U == '1');"
]
},
{
"pattern": "0 1 U#1 1 1 1 1 0 0 sz#1 1 0 0 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTAS <V><d>, <V><n>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 32 << UInt(sz);",
"integer datasize = esize;",
"integer elements = 1;",
"",
"FPRounding rounding = FPRounding_TIEAWAY;",
"boolean unsigned = (U == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 a#1 1 1 1 1 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTAS <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"FPRounding rounding = FPRounding_TIEAWAY;",
"boolean unsigned = (U == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 0 sz#1 1 0 0 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTAS <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"FPRounding rounding = FPRounding_TIEAWAY;",
"boolean unsigned = (U == '1');"
]
}
],
"name": "FCVTAS (vector)",
"description": [
"Floating-point Convert to Signed integer, rounding to nearest with ties to Away (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"",
"bits(fltsize) fltval;",
"bits(intsize) intval;",
"",
"case op of",
" when FPConvOp_CVT_FtoI",
" fltval = V[n];",
" intval = FPToFixed(fltval, 0, unsigned, FPCR, rounding);",
" X[d] = intval;",
" when FPConvOp_CVT_ItoF",
" intval = X[n];",
" fltval = FixedToFP(intval, 0, unsigned, FPCR, rounding);",
" V[d] = fltval;",
" when FPConvOp_MOV_FtoI",
" fltval = Vpart[n,part];",
" intval = ZeroExtend(fltval, intsize);",
" X[d] = intval;",
" when FPConvOp_MOV_ItoF",
" intval = X[n];",
" fltval = intval;",
" Vpart[d,part] = fltval;"
],
"variants": [
{
"pattern": "sf#1 0 S#1 1 1 1 1 0 type#2 1 rmode#2 opcode#3 0 0 0 0 0 0 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0 && type == 11",
"format": "FCVTAS <Wd>, <Hn>"
},
{
"condition": "sf == 1 && type == 11",
"format": "FCVTAS <Xd>, <Hn>"
},
{
"condition": "sf == 0 && type == 00",
"format": "FCVTAS <Wd>, <Sn>"
},
{
"condition": "sf == 1 && type == 00",
"format": "FCVTAS <Xd>, <Sn>"
},
{
"condition": "sf == 0 && type == 01",
"format": "FCVTAS <Wd>, <Dn>"
},
{
"condition": "sf == 1 && type == 01",
"format": "FCVTAS <Xd>, <Dn>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer intsize = if sf == '1' then 64 else 32;",
"integer fltsize;",
"FPConvOp op;",
"FPRounding rounding;",
"boolean unsigned;",
"integer part;",
"",
"case type of",
" when '00'",
" fltsize = 32;",
" when '01' ",
" fltsize = 64;",
" when '10' ",
" if opcode<2:1>:rmode != '11 01' then UnallocatedEncoding();",
" fltsize = 128;",
" when '11' ",
" if HaveFP16Ext() then",
" fltsize = 16;",
" else",
" UnallocatedEncoding();",
"",
"case opcode<2:1>:rmode of",
" when '00 xx' // FCVT[NPMZ][US]",
" rounding = FPDecodeRounding(rmode);",
" unsigned = (opcode<0> == '1');",
" op = FPConvOp_CVT_FtoI;",
" when '01 00' // [US]CVTF",
" rounding = FPRoundingMode(FPCR);",
" unsigned = (opcode<0> == '1');",
" op = FPConvOp_CVT_ItoF;",
" when '10 00' // FCVTA[US]",
" rounding = FPRounding_TIEAWAY;",
" unsigned = (opcode<0> == '1');",
" op = FPConvOp_CVT_FtoI;",
" when '11 00' // FMOV",
" if fltsize != 16 && fltsize != intsize then UnallocatedEncoding();",
" op = if opcode<0> == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI;",
" part = 0;",
" when '11 01' // FMOV D[1]",
" if intsize != 64 || fltsize != 128 then UnallocatedEncoding();",
" op = if opcode<0> == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI;",
" part = 1;",
" fltsize = 64; // size of D[1] is 64",
" otherwise ",
" UnallocatedEncoding();"
]
}
],
"name": "FCVTAS (scalar)",
"description": [
"Floating-point Convert to Signed integer, rounding to nearest with ties to Away (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"bits(datasize) result;",
"bits(esize) element;",
"",
"for e = 0 to elements-1",
" element = Elem[operand, e, esize];",
" Elem[result, e, esize] = FPToFixed(element, 0, unsigned, FPCR, rounding);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 0 size<1>#1 1 1 1 1 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTAU <Hd>, <Hn>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = esize;",
"integer elements = 1;",
"",
"FPRounding rounding = FPRounding_TIEAWAY;",
"boolean unsigned = (U == '1');"
]
},
{
"pattern": "0 1 U#1 1 1 1 1 0 0 sz#1 1 0 0 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTAU <V><d>, <V><n>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 32 << UInt(sz);",
"integer datasize = esize;",
"integer elements = 1;",
"",
"FPRounding rounding = FPRounding_TIEAWAY;",
"boolean unsigned = (U == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 a#1 1 1 1 1 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTAU <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"FPRounding rounding = FPRounding_TIEAWAY;",
"boolean unsigned = (U == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 0 sz#1 1 0 0 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTAU <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"FPRounding rounding = FPRounding_TIEAWAY;",
"boolean unsigned = (U == '1');"
]
}
],
"name": "FCVTAU (vector)",
"description": [
"Floating-point Convert to Unsigned integer, rounding to nearest with ties to Away (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"",
"bits(fltsize) fltval;",
"bits(intsize) intval;",
"",
"case op of",
" when FPConvOp_CVT_FtoI",
" fltval = V[n];",
" intval = FPToFixed(fltval, 0, unsigned, FPCR, rounding);",
" X[d] = intval;",
" when FPConvOp_CVT_ItoF",
" intval = X[n];",
" fltval = FixedToFP(intval, 0, unsigned, FPCR, rounding);",
" V[d] = fltval;",
" when FPConvOp_MOV_FtoI",
" fltval = Vpart[n,part];",
" intval = ZeroExtend(fltval, intsize);",
" X[d] = intval;",
" when FPConvOp_MOV_ItoF",
" intval = X[n];",
" fltval = intval;",
" Vpart[d,part] = fltval;"
],
"variants": [
{
"pattern": "sf#1 0 S#1 1 1 1 1 0 type#2 1 rmode#2 opcode#3 0 0 0 0 0 0 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0 && type == 11",
"format": "FCVTAU <Wd>, <Hn>"
},
{
"condition": "sf == 1 && type == 11",
"format": "FCVTAU <Xd>, <Hn>"
},
{
"condition": "sf == 0 && type == 00",
"format": "FCVTAU <Wd>, <Sn>"
},
{
"condition": "sf == 1 && type == 00",
"format": "FCVTAU <Xd>, <Sn>"
},
{
"condition": "sf == 0 && type == 01",
"format": "FCVTAU <Wd>, <Dn>"
},
{
"condition": "sf == 1 && type == 01",
"format": "FCVTAU <Xd>, <Dn>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer intsize = if sf == '1' then 64 else 32;",
"integer fltsize;",
"FPConvOp op;",
"FPRounding rounding;",
"boolean unsigned;",
"integer part;",
"",
"case type of",
" when '00'",
" fltsize = 32;",
" when '01' ",
" fltsize = 64;",
" when '10' ",
" if opcode<2:1>:rmode != '11 01' then UnallocatedEncoding();",
" fltsize = 128;",
" when '11' ",
" if HaveFP16Ext() then",
" fltsize = 16;",
" else",
" UnallocatedEncoding();",
"",
"case opcode<2:1>:rmode of",
" when '00 xx' // FCVT[NPMZ][US]",
" rounding = FPDecodeRounding(rmode);",
" unsigned = (opcode<0> == '1');",
" op = FPConvOp_CVT_FtoI;",
" when '01 00' // [US]CVTF",
" rounding = FPRoundingMode(FPCR);",
" unsigned = (opcode<0> == '1');",
" op = FPConvOp_CVT_ItoF;",
" when '10 00' // FCVTA[US]",
" rounding = FPRounding_TIEAWAY;",
" unsigned = (opcode<0> == '1');",
" op = FPConvOp_CVT_FtoI;",
" when '11 00' // FMOV",
" if fltsize != 16 && fltsize != intsize then UnallocatedEncoding();",
" op = if opcode<0> == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI;",
" part = 0;",
" when '11 01' // FMOV D[1]",
" if intsize != 64 || fltsize != 128 then UnallocatedEncoding();",
" op = if opcode<0> == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI;",
" part = 1;",
" fltsize = 64; // size of D[1] is 64",
" otherwise ",
" UnallocatedEncoding();"
]
}
],
"name": "FCVTAU (scalar)",
"description": [
"Floating-point Convert to Unsigned integer, rounding to nearest with ties to Away (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = Vpart[n, part];",
"bits(2*datasize) result;",
"",
"for e = 0 to elements-1",
" Elem[result, e, 2*esize] = FPConvert(Elem[operand, e, esize], FPCR);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 0 sz#1 1 0 0 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTL{2} <Vd>.<Ta>, <Vn>.<Tb>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16 << UInt(sz);",
"integer datasize = 64;",
"integer part = UInt(Q);",
"integer elements = datasize DIV esize;"
]
}
],
"name": "FCVTL, FCVTL2",
"description": [
"Floating-point Convert to higher precision Long (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"bits(datasize) result;",
"bits(esize) element;",
"",
"for e = 0 to elements-1",
" element = Elem[operand, e, esize];",
" Elem[result, e, esize] = FPToFixed(element, 0, unsigned, FPCR, rounding);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 0 o2#1 1 1 1 1 0 0 1 1 0 1 o1#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTMS <Hd>, <Hn>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = esize;",
"integer elements = 1;",
"",
"FPRounding rounding = FPDecodeRounding(o1:o2);",
"boolean unsigned = (U == '1');"
]
},
{
"pattern": "0 1 U#1 1 1 1 1 0 o2#1 sz#1 1 0 0 0 0 1 1 0 1 o1#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTMS <V><d>, <V><n>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 32 << UInt(sz);",
"integer datasize = esize;",
"integer elements = 1;",
"",
"FPRounding rounding = FPDecodeRounding(o1:o2);",
"boolean unsigned = (U == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o2#1 1 1 1 1 0 0 1 1 0 1 o1#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTMS <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"FPRounding rounding = FPDecodeRounding(o1:o2);",
"boolean unsigned = (U == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o2#1 sz#1 1 0 0 0 0 1 1 0 1 o1#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTMS <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"FPRounding rounding = FPDecodeRounding(o1:o2);",
"boolean unsigned = (U == '1');"
]
}
],
"name": "FCVTMS (vector)",
"description": [
"Floating-point Convert to Signed integer, rounding toward Minus infinity (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"",
"bits(fltsize) fltval;",
"bits(intsize) intval;",
"",
"case op of",
" when FPConvOp_CVT_FtoI",
" fltval = V[n];",
" intval = FPToFixed(fltval, 0, unsigned, FPCR, rounding);",
" X[d] = intval;",
" when FPConvOp_CVT_ItoF",
" intval = X[n];",
" fltval = FixedToFP(intval, 0, unsigned, FPCR, rounding);",
" V[d] = fltval;",
" when FPConvOp_MOV_FtoI",
" fltval = Vpart[n,part];",
" intval = ZeroExtend(fltval, intsize);",
" X[d] = intval;",
" when FPConvOp_MOV_ItoF",
" intval = X[n];",
" fltval = intval;",
" Vpart[d,part] = fltval;"
],
"variants": [
{
"pattern": "sf#1 0 S#1 1 1 1 1 0 type#2 1 rmode#2 opcode#3 0 0 0 0 0 0 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0 && type == 11",
"format": "FCVTMS <Wd>, <Hn>"
},
{
"condition": "sf == 1 && type == 11",
"format": "FCVTMS <Xd>, <Hn>"
},
{
"condition": "sf == 0 && type == 00",
"format": "FCVTMS <Wd>, <Sn>"
},
{
"condition": "sf == 1 && type == 00",
"format": "FCVTMS <Xd>, <Sn>"
},
{
"condition": "sf == 0 && type == 01",
"format": "FCVTMS <Wd>, <Dn>"
},
{
"condition": "sf == 1 && type == 01",
"format": "FCVTMS <Xd>, <Dn>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer intsize = if sf == '1' then 64 else 32;",
"integer fltsize;",
"FPConvOp op;",
"FPRounding rounding;",
"boolean unsigned;",
"integer part;",
"",
"case type of",
" when '00'",
" fltsize = 32;",
" when '01' ",
" fltsize = 64;",
" when '10' ",
" if opcode<2:1>:rmode != '11 01' then UnallocatedEncoding();",
" fltsize = 128;",
" when '11' ",
" if HaveFP16Ext() then",
" fltsize = 16;",
" else",
" UnallocatedEncoding();",
"",
"case opcode<2:1>:rmode of",
" when '00 xx' // FCVT[NPMZ][US]",
" rounding = FPDecodeRounding(rmode);",
" unsigned = (opcode<0> == '1');",
" op = FPConvOp_CVT_FtoI;",
" when '01 00' // [US]CVTF",
" rounding = FPRoundingMode(FPCR);",
" unsigned = (opcode<0> == '1');",
" op = FPConvOp_CVT_ItoF;",
" when '10 00' // FCVTA[US]",
" rounding = FPRounding_TIEAWAY;",
" unsigned = (opcode<0> == '1');",
" op = FPConvOp_CVT_FtoI;",
" when '11 00' // FMOV",
" if fltsize != 16 && fltsize != intsize then UnallocatedEncoding();",
" op = if opcode<0> == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI;",
" part = 0;",
" when '11 01' // FMOV D[1]",
" if intsize != 64 || fltsize != 128 then UnallocatedEncoding();",
" op = if opcode<0> == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI;",
" part = 1;",
" fltsize = 64; // size of D[1] is 64",
" otherwise ",
" UnallocatedEncoding();"
]
}
],
"name": "FCVTMS (scalar)",
"description": [
"Floating-point Convert to Signed integer, rounding toward Minus infinity (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"bits(datasize) result;",
"bits(esize) element;",
"",
"for e = 0 to elements-1",
" element = Elem[operand, e, esize];",
" Elem[result, e, esize] = FPToFixed(element, 0, unsigned, FPCR, rounding);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 0 o2#1 1 1 1 1 0 0 1 1 0 1 o1#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTMU <Hd>, <Hn>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = esize;",
"integer elements = 1;",
"",
"FPRounding rounding = FPDecodeRounding(o1:o2);",
"boolean unsigned = (U == '1');"
]
},
{
"pattern": "0 1 U#1 1 1 1 1 0 o2#1 sz#1 1 0 0 0 0 1 1 0 1 o1#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTMU <V><d>, <V><n>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 32 << UInt(sz);",
"integer datasize = esize;",
"integer elements = 1;",
"",
"FPRounding rounding = FPDecodeRounding(o1:o2);",
"boolean unsigned = (U == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o2#1 1 1 1 1 0 0 1 1 0 1 o1#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTMU <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"FPRounding rounding = FPDecodeRounding(o1:o2);",
"boolean unsigned = (U == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o2#1 sz#1 1 0 0 0 0 1 1 0 1 o1#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTMU <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"FPRounding rounding = FPDecodeRounding(o1:o2);",
"boolean unsigned = (U == '1');"
]
}
],
"name": "FCVTMU (vector)",
"description": [
"Floating-point Convert to Unsigned integer, rounding toward Minus infinity (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"",
"bits(fltsize) fltval;",
"bits(intsize) intval;",
"",
"case op of",
" when FPConvOp_CVT_FtoI",
" fltval = V[n];",
" intval = FPToFixed(fltval, 0, unsigned, FPCR, rounding);",
" X[d] = intval;",
" when FPConvOp_CVT_ItoF",
" intval = X[n];",
" fltval = FixedToFP(intval, 0, unsigned, FPCR, rounding);",
" V[d] = fltval;",
" when FPConvOp_MOV_FtoI",
" fltval = Vpart[n,part];",
" intval = ZeroExtend(fltval, intsize);",
" X[d] = intval;",
" when FPConvOp_MOV_ItoF",
" intval = X[n];",
" fltval = intval;",
" Vpart[d,part] = fltval;"
],
"variants": [
{
"pattern": "sf#1 0 S#1 1 1 1 1 0 type#2 1 rmode#2 opcode#3 0 0 0 0 0 0 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0 && type == 11",
"format": "FCVTMU <Wd>, <Hn>"
},
{
"condition": "sf == 1 && type == 11",
"format": "FCVTMU <Xd>, <Hn>"
},
{
"condition": "sf == 0 && type == 00",
"format": "FCVTMU <Wd>, <Sn>"
},
{
"condition": "sf == 1 && type == 00",
"format": "FCVTMU <Xd>, <Sn>"
},
{
"condition": "sf == 0 && type == 01",
"format": "FCVTMU <Wd>, <Dn>"
},
{
"condition": "sf == 1 && type == 01",
"format": "FCVTMU <Xd>, <Dn>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer intsize = if sf == '1' then 64 else 32;",
"integer fltsize;",
"FPConvOp op;",
"FPRounding rounding;",
"boolean unsigned;",
"integer part;",
"",
"case type of",
" when '00'",
" fltsize = 32;",
" when '01' ",
" fltsize = 64;",
" when '10' ",
" if opcode<2:1>:rmode != '11 01' then UnallocatedEncoding();",
" fltsize = 128;",
" when '11' ",
" if HaveFP16Ext() then",
" fltsize = 16;",
" else",
" UnallocatedEncoding();",
"",
"case opcode<2:1>:rmode of",
" when '00 xx' // FCVT[NPMZ][US]",
" rounding = FPDecodeRounding(rmode);",
" unsigned = (opcode<0> == '1');",
" op = FPConvOp_CVT_FtoI;",
" when '01 00' // [US]CVTF",
" rounding = FPRoundingMode(FPCR);",
" unsigned = (opcode<0> == '1');",
" op = FPConvOp_CVT_ItoF;",
" when '10 00' // FCVTA[US]",
" rounding = FPRounding_TIEAWAY;",
" unsigned = (opcode<0> == '1');",
" op = FPConvOp_CVT_FtoI;",
" when '11 00' // FMOV",
" if fltsize != 16 && fltsize != intsize then UnallocatedEncoding();",
" op = if opcode<0> == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI;",
" part = 0;",
" when '11 01' // FMOV D[1]",
" if intsize != 64 || fltsize != 128 then UnallocatedEncoding();",
" op = if opcode<0> == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI;",
" part = 1;",
" fltsize = 64; // size of D[1] is 64",
" otherwise ",
" UnallocatedEncoding();"
]
}
],
"name": "FCVTMU (scalar)",
"description": [
"Floating-point Convert to Unsigned integer, rounding toward Minus infinity (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(2*datasize) operand = V[n];",
"bits(datasize) result;",
"",
"for e = 0 to elements-1",
" Elem[result, e, esize] = FPConvert(Elem[operand, e, 2*esize], FPCR);",
"",
"Vpart[d, part] = result;"
],
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 0 sz#1 1 0 0 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTN{2} <Vd>.<Tb>, <Vn>.<Ta>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16 << UInt(sz);",
"integer datasize = 64;",
"integer part = UInt(Q);",
"integer elements = datasize DIV esize;"
]
}
],
"name": "FCVTN, FCVTN2",
"description": [
"Floating-point Convert to lower precision Narrow (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"bits(datasize) result;",
"bits(esize) element;",
"",
"for e = 0 to elements-1",
" element = Elem[operand, e, esize];",
" Elem[result, e, esize] = FPToFixed(element, 0, unsigned, FPCR, rounding);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 0 o2#1 1 1 1 1 0 0 1 1 0 1 o1#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTNS <Hd>, <Hn>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = esize;",
"integer elements = 1;",
"",
"FPRounding rounding = FPDecodeRounding(o1:o2);",
"boolean unsigned = (U == '1');"
]
},
{
"pattern": "0 1 U#1 1 1 1 1 0 o2#1 sz#1 1 0 0 0 0 1 1 0 1 o1#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTNS <V><d>, <V><n>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 32 << UInt(sz);",
"integer datasize = esize;",
"integer elements = 1;",
"",
"FPRounding rounding = FPDecodeRounding(o1:o2);",
"boolean unsigned = (U == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o2#1 1 1 1 1 0 0 1 1 0 1 o1#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTNS <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"FPRounding rounding = FPDecodeRounding(o1:o2);",
"boolean unsigned = (U == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o2#1 sz#1 1 0 0 0 0 1 1 0 1 o1#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTNS <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"FPRounding rounding = FPDecodeRounding(o1:o2);",
"boolean unsigned = (U == '1');"
]
}
],
"name": "FCVTNS (vector)",
"description": [
"Floating-point Convert to Signed integer, rounding to nearest with ties to even (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"",
"bits(fltsize) fltval;",
"bits(intsize) intval;",
"",
"case op of",
" when FPConvOp_CVT_FtoI",
" fltval = V[n];",
" intval = FPToFixed(fltval, 0, unsigned, FPCR, rounding);",
" X[d] = intval;",
" when FPConvOp_CVT_ItoF",
" intval = X[n];",
" fltval = FixedToFP(intval, 0, unsigned, FPCR, rounding);",
" V[d] = fltval;",
" when FPConvOp_MOV_FtoI",
" fltval = Vpart[n,part];",
" intval = ZeroExtend(fltval, intsize);",
" X[d] = intval;",
" when FPConvOp_MOV_ItoF",
" intval = X[n];",
" fltval = intval;",
" Vpart[d,part] = fltval;"
],
"variants": [
{
"pattern": "sf#1 0 S#1 1 1 1 1 0 type#2 1 rmode#2 opcode#3 0 0 0 0 0 0 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0 && type == 11",
"format": "FCVTNS <Wd>, <Hn>"
},
{
"condition": "sf == 1 && type == 11",
"format": "FCVTNS <Xd>, <Hn>"
},
{
"condition": "sf == 0 && type == 00",
"format": "FCVTNS <Wd>, <Sn>"
},
{
"condition": "sf == 1 && type == 00",
"format": "FCVTNS <Xd>, <Sn>"
},
{
"condition": "sf == 0 && type == 01",
"format": "FCVTNS <Wd>, <Dn>"
},
{
"condition": "sf == 1 && type == 01",
"format": "FCVTNS <Xd>, <Dn>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer intsize = if sf == '1' then 64 else 32;",
"integer fltsize;",
"FPConvOp op;",
"FPRounding rounding;",
"boolean unsigned;",
"integer part;",
"",
"case type of",
" when '00'",
" fltsize = 32;",
" when '01' ",
" fltsize = 64;",
" when '10' ",
" if opcode<2:1>:rmode != '11 01' then UnallocatedEncoding();",
" fltsize = 128;",
" when '11' ",
" if HaveFP16Ext() then",
" fltsize = 16;",
" else",
" UnallocatedEncoding();",
"",
"case opcode<2:1>:rmode of",
" when '00 xx' // FCVT[NPMZ][US]",
" rounding = FPDecodeRounding(rmode);",
" unsigned = (opcode<0> == '1');",
" op = FPConvOp_CVT_FtoI;",
" when '01 00' // [US]CVTF",
" rounding = FPRoundingMode(FPCR);",
" unsigned = (opcode<0> == '1');",
" op = FPConvOp_CVT_ItoF;",
" when '10 00' // FCVTA[US]",
" rounding = FPRounding_TIEAWAY;",
" unsigned = (opcode<0> == '1');",
" op = FPConvOp_CVT_FtoI;",
" when '11 00' // FMOV",
" if fltsize != 16 && fltsize != intsize then UnallocatedEncoding();",
" op = if opcode<0> == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI;",
" part = 0;",
" when '11 01' // FMOV D[1]",
" if intsize != 64 || fltsize != 128 then UnallocatedEncoding();",
" op = if opcode<0> == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI;",
" part = 1;",
" fltsize = 64; // size of D[1] is 64",
" otherwise ",
" UnallocatedEncoding();"
]
}
],
"name": "FCVTNS (scalar)",
"description": [
"Floating-point Convert to Signed integer, rounding to nearest with ties to even (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"bits(datasize) result;",
"bits(esize) element;",
"",
"for e = 0 to elements-1",
" element = Elem[operand, e, esize];",
" Elem[result, e, esize] = FPToFixed(element, 0, unsigned, FPCR, rounding);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 0 o2#1 1 1 1 1 0 0 1 1 0 1 o1#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTNU <Hd>, <Hn>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = esize;",
"integer elements = 1;",
"",
"FPRounding rounding = FPDecodeRounding(o1:o2);",
"boolean unsigned = (U == '1');"
]
},
{
"pattern": "0 1 U#1 1 1 1 1 0 o2#1 sz#1 1 0 0 0 0 1 1 0 1 o1#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTNU <V><d>, <V><n>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 32 << UInt(sz);",
"integer datasize = esize;",
"integer elements = 1;",
"",
"FPRounding rounding = FPDecodeRounding(o1:o2);",
"boolean unsigned = (U == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o2#1 1 1 1 1 0 0 1 1 0 1 o1#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTNU <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"FPRounding rounding = FPDecodeRounding(o1:o2);",
"boolean unsigned = (U == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o2#1 sz#1 1 0 0 0 0 1 1 0 1 o1#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTNU <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"FPRounding rounding = FPDecodeRounding(o1:o2);",
"boolean unsigned = (U == '1');"
]
}
],
"name": "FCVTNU (vector)",
"description": [
"Floating-point Convert to Unsigned integer, rounding to nearest with ties to even (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"",
"bits(fltsize) fltval;",
"bits(intsize) intval;",
"",
"case op of",
" when FPConvOp_CVT_FtoI",
" fltval = V[n];",
" intval = FPToFixed(fltval, 0, unsigned, FPCR, rounding);",
" X[d] = intval;",
" when FPConvOp_CVT_ItoF",
" intval = X[n];",
" fltval = FixedToFP(intval, 0, unsigned, FPCR, rounding);",
" V[d] = fltval;",
" when FPConvOp_MOV_FtoI",
" fltval = Vpart[n,part];",
" intval = ZeroExtend(fltval, intsize);",
" X[d] = intval;",
" when FPConvOp_MOV_ItoF",
" intval = X[n];",
" fltval = intval;",
" Vpart[d,part] = fltval;"
],
"variants": [
{
"pattern": "sf#1 0 S#1 1 1 1 1 0 type#2 1 rmode#2 opcode#3 0 0 0 0 0 0 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0 && type == 11",
"format": "FCVTNU <Wd>, <Hn>"
},
{
"condition": "sf == 1 && type == 11",
"format": "FCVTNU <Xd>, <Hn>"
},
{
"condition": "sf == 0 && type == 00",
"format": "FCVTNU <Wd>, <Sn>"
},
{
"condition": "sf == 1 && type == 00",
"format": "FCVTNU <Xd>, <Sn>"
},
{
"condition": "sf == 0 && type == 01",
"format": "FCVTNU <Wd>, <Dn>"
},
{
"condition": "sf == 1 && type == 01",
"format": "FCVTNU <Xd>, <Dn>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer intsize = if sf == '1' then 64 else 32;",
"integer fltsize;",
"FPConvOp op;",
"FPRounding rounding;",
"boolean unsigned;",
"integer part;",
"",
"case type of",
" when '00'",
" fltsize = 32;",
" when '01' ",
" fltsize = 64;",
" when '10' ",
" if opcode<2:1>:rmode != '11 01' then UnallocatedEncoding();",
" fltsize = 128;",
" when '11' ",
" if HaveFP16Ext() then",
" fltsize = 16;",
" else",
" UnallocatedEncoding();",
"",
"case opcode<2:1>:rmode of",
" when '00 xx' // FCVT[NPMZ][US]",
" rounding = FPDecodeRounding(rmode);",
" unsigned = (opcode<0> == '1');",
" op = FPConvOp_CVT_FtoI;",
" when '01 00' // [US]CVTF",
" rounding = FPRoundingMode(FPCR);",
" unsigned = (opcode<0> == '1');",
" op = FPConvOp_CVT_ItoF;",
" when '10 00' // FCVTA[US]",
" rounding = FPRounding_TIEAWAY;",
" unsigned = (opcode<0> == '1');",
" op = FPConvOp_CVT_FtoI;",
" when '11 00' // FMOV",
" if fltsize != 16 && fltsize != intsize then UnallocatedEncoding();",
" op = if opcode<0> == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI;",
" part = 0;",
" when '11 01' // FMOV D[1]",
" if intsize != 64 || fltsize != 128 then UnallocatedEncoding();",
" op = if opcode<0> == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI;",
" part = 1;",
" fltsize = 64; // size of D[1] is 64",
" otherwise ",
" UnallocatedEncoding();"
]
}
],
"name": "FCVTNU (scalar)",
"description": [
"Floating-point Convert to Unsigned integer, rounding to nearest with ties to even (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"bits(datasize) result;",
"bits(esize) element;",
"",
"for e = 0 to elements-1",
" element = Elem[operand, e, esize];",
" Elem[result, e, esize] = FPToFixed(element, 0, unsigned, FPCR, rounding);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 0 o2#1 1 1 1 1 0 0 1 1 0 1 o1#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTPS <Hd>, <Hn>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = esize;",
"integer elements = 1;",
"",
"FPRounding rounding = FPDecodeRounding(o1:o2);",
"boolean unsigned = (U == '1');"
]
},
{
"pattern": "0 1 U#1 1 1 1 1 0 o2#1 sz#1 1 0 0 0 0 1 1 0 1 o1#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTPS <V><d>, <V><n>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 32 << UInt(sz);",
"integer datasize = esize;",
"integer elements = 1;",
"",
"FPRounding rounding = FPDecodeRounding(o1:o2);",
"boolean unsigned = (U == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o2#1 1 1 1 1 0 0 1 1 0 1 o1#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTPS <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"FPRounding rounding = FPDecodeRounding(o1:o2);",
"boolean unsigned = (U == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o2#1 sz#1 1 0 0 0 0 1 1 0 1 o1#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTPS <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"FPRounding rounding = FPDecodeRounding(o1:o2);",
"boolean unsigned = (U == '1');"
]
}
],
"name": "FCVTPS (vector)",
"description": [
"Floating-point Convert to Signed integer, rounding toward Plus infinity (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"",
"bits(fltsize) fltval;",
"bits(intsize) intval;",
"",
"case op of",
" when FPConvOp_CVT_FtoI",
" fltval = V[n];",
" intval = FPToFixed(fltval, 0, unsigned, FPCR, rounding);",
" X[d] = intval;",
" when FPConvOp_CVT_ItoF",
" intval = X[n];",
" fltval = FixedToFP(intval, 0, unsigned, FPCR, rounding);",
" V[d] = fltval;",
" when FPConvOp_MOV_FtoI",
" fltval = Vpart[n,part];",
" intval = ZeroExtend(fltval, intsize);",
" X[d] = intval;",
" when FPConvOp_MOV_ItoF",
" intval = X[n];",
" fltval = intval;",
" Vpart[d,part] = fltval;"
],
"variants": [
{
"pattern": "sf#1 0 S#1 1 1 1 1 0 type#2 1 rmode#2 opcode#3 0 0 0 0 0 0 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0 && type == 11",
"format": "FCVTPS <Wd>, <Hn>"
},
{
"condition": "sf == 1 && type == 11",
"format": "FCVTPS <Xd>, <Hn>"
},
{
"condition": "sf == 0 && type == 00",
"format": "FCVTPS <Wd>, <Sn>"
},
{
"condition": "sf == 1 && type == 00",
"format": "FCVTPS <Xd>, <Sn>"
},
{
"condition": "sf == 0 && type == 01",
"format": "FCVTPS <Wd>, <Dn>"
},
{
"condition": "sf == 1 && type == 01",
"format": "FCVTPS <Xd>, <Dn>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer intsize = if sf == '1' then 64 else 32;",
"integer fltsize;",
"FPConvOp op;",
"FPRounding rounding;",
"boolean unsigned;",
"integer part;",
"",
"case type of",
" when '00'",
" fltsize = 32;",
" when '01' ",
" fltsize = 64;",
" when '10' ",
" if opcode<2:1>:rmode != '11 01' then UnallocatedEncoding();",
" fltsize = 128;",
" when '11' ",
" if HaveFP16Ext() then",
" fltsize = 16;",
" else",
" UnallocatedEncoding();",
"",
"case opcode<2:1>:rmode of",
" when '00 xx' // FCVT[NPMZ][US]",
" rounding = FPDecodeRounding(rmode);",
" unsigned = (opcode<0> == '1');",
" op = FPConvOp_CVT_FtoI;",
" when '01 00' // [US]CVTF",
" rounding = FPRoundingMode(FPCR);",
" unsigned = (opcode<0> == '1');",
" op = FPConvOp_CVT_ItoF;",
" when '10 00' // FCVTA[US]",
" rounding = FPRounding_TIEAWAY;",
" unsigned = (opcode<0> == '1');",
" op = FPConvOp_CVT_FtoI;",
" when '11 00' // FMOV",
" if fltsize != 16 && fltsize != intsize then UnallocatedEncoding();",
" op = if opcode<0> == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI;",
" part = 0;",
" when '11 01' // FMOV D[1]",
" if intsize != 64 || fltsize != 128 then UnallocatedEncoding();",
" op = if opcode<0> == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI;",
" part = 1;",
" fltsize = 64; // size of D[1] is 64",
" otherwise ",
" UnallocatedEncoding();"
]
}
],
"name": "FCVTPS (scalar)",
"description": [
"Floating-point Convert to Signed integer, rounding toward Plus infinity (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"bits(datasize) result;",
"bits(esize) element;",
"",
"for e = 0 to elements-1",
" element = Elem[operand, e, esize];",
" Elem[result, e, esize] = FPToFixed(element, 0, unsigned, FPCR, rounding);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 0 o2#1 1 1 1 1 0 0 1 1 0 1 o1#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTPU <Hd>, <Hn>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = esize;",
"integer elements = 1;",
"",
"FPRounding rounding = FPDecodeRounding(o1:o2);",
"boolean unsigned = (U == '1');"
]
},
{
"pattern": "0 1 U#1 1 1 1 1 0 o2#1 sz#1 1 0 0 0 0 1 1 0 1 o1#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTPU <V><d>, <V><n>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 32 << UInt(sz);",
"integer datasize = esize;",
"integer elements = 1;",
"",
"FPRounding rounding = FPDecodeRounding(o1:o2);",
"boolean unsigned = (U == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o2#1 1 1 1 1 0 0 1 1 0 1 o1#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTPU <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"FPRounding rounding = FPDecodeRounding(o1:o2);",
"boolean unsigned = (U == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o2#1 sz#1 1 0 0 0 0 1 1 0 1 o1#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTPU <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"FPRounding rounding = FPDecodeRounding(o1:o2);",
"boolean unsigned = (U == '1');"
]
}
],
"name": "FCVTPU (vector)",
"description": [
"Floating-point Convert to Unsigned integer, rounding toward Plus infinity (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"",
"bits(fltsize) fltval;",
"bits(intsize) intval;",
"",
"case op of",
" when FPConvOp_CVT_FtoI",
" fltval = V[n];",
" intval = FPToFixed(fltval, 0, unsigned, FPCR, rounding);",
" X[d] = intval;",
" when FPConvOp_CVT_ItoF",
" intval = X[n];",
" fltval = FixedToFP(intval, 0, unsigned, FPCR, rounding);",
" V[d] = fltval;",
" when FPConvOp_MOV_FtoI",
" fltval = Vpart[n,part];",
" intval = ZeroExtend(fltval, intsize);",
" X[d] = intval;",
" when FPConvOp_MOV_ItoF",
" intval = X[n];",
" fltval = intval;",
" Vpart[d,part] = fltval;"
],
"variants": [
{
"pattern": "sf#1 0 S#1 1 1 1 1 0 type#2 1 rmode#2 opcode#3 0 0 0 0 0 0 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0 && type == 11",
"format": "FCVTPU <Wd>, <Hn>"
},
{
"condition": "sf == 1 && type == 11",
"format": "FCVTPU <Xd>, <Hn>"
},
{
"condition": "sf == 0 && type == 00",
"format": "FCVTPU <Wd>, <Sn>"
},
{
"condition": "sf == 1 && type == 00",
"format": "FCVTPU <Xd>, <Sn>"
},
{
"condition": "sf == 0 && type == 01",
"format": "FCVTPU <Wd>, <Dn>"
},
{
"condition": "sf == 1 && type == 01",
"format": "FCVTPU <Xd>, <Dn>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer intsize = if sf == '1' then 64 else 32;",
"integer fltsize;",
"FPConvOp op;",
"FPRounding rounding;",
"boolean unsigned;",
"integer part;",
"",
"case type of",
" when '00'",
" fltsize = 32;",
" when '01' ",
" fltsize = 64;",
" when '10' ",
" if opcode<2:1>:rmode != '11 01' then UnallocatedEncoding();",
" fltsize = 128;",
" when '11' ",
" if HaveFP16Ext() then",
" fltsize = 16;",
" else",
" UnallocatedEncoding();",
"",
"case opcode<2:1>:rmode of",
" when '00 xx' // FCVT[NPMZ][US]",
" rounding = FPDecodeRounding(rmode);",
" unsigned = (opcode<0> == '1');",
" op = FPConvOp_CVT_FtoI;",
" when '01 00' // [US]CVTF",
" rounding = FPRoundingMode(FPCR);",
" unsigned = (opcode<0> == '1');",
" op = FPConvOp_CVT_ItoF;",
" when '10 00' // FCVTA[US]",
" rounding = FPRounding_TIEAWAY;",
" unsigned = (opcode<0> == '1');",
" op = FPConvOp_CVT_FtoI;",
" when '11 00' // FMOV",
" if fltsize != 16 && fltsize != intsize then UnallocatedEncoding();",
" op = if opcode<0> == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI;",
" part = 0;",
" when '11 01' // FMOV D[1]",
" if intsize != 64 || fltsize != 128 then UnallocatedEncoding();",
" op = if opcode<0> == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI;",
" part = 1;",
" fltsize = 64; // size of D[1] is 64",
" otherwise ",
" UnallocatedEncoding();"
]
}
],
"name": "FCVTPU (scalar)",
"description": [
"Floating-point Convert to Unsigned integer, rounding toward Plus infinity (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(2*datasize) operand = V[n];",
"bits(datasize) result;",
"",
"for e = 0 to elements-1",
" Elem[result, e, esize] = FPConvert(Elem[operand, e, 2*esize], FPCR, FPRounding_ODD);",
"",
"Vpart[d, part] = result;"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 0 0 sz#1 1 0 0 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTXN <Vb><d>, <Va><n>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if sz == '0' then ReservedValue();",
"integer esize = 32;",
"integer datasize = esize;",
"integer elements = 1;",
"integer part = 0;"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 0 sz#1 1 0 0 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTXN{2} <Vd>.<Tb>, <Vn>.<Ta>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if sz == '0' then ReservedValue();",
"integer esize = 32;",
"integer datasize = 64;",
"integer elements = 2;",
"integer part = UInt(Q);"
]
}
],
"name": "FCVTXN, FCVTXN2",
"description": [
"Floating-point Convert to lower precision Narrow, rounding to odd (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"bits(datasize) result;",
"bits(esize) element;",
"",
"for e = 0 to elements-1",
" element = Elem[operand, e, esize];",
" Elem[result, e, esize] = FPToFixed(element, fracbits, unsigned, FPCR, rounding);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 1 0 immh#4 immb#3 opcode#5 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTZS <V><d>, <V><n>, #<fbits>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if immh == '000x' || (immh == '001x' && !HaveFP16Ext()) then ReservedValue();",
"integer esize = if immh == '1xxx' then 64 else if immh == '01xx' then 32 else 16;",
"integer datasize = esize;",
"integer elements = 1;",
"",
"integer fracbits = (esize * 2) - UInt(immh:immb);",
"boolean unsigned = (U == '1');",
"FPRounding rounding = FPRounding_ZERO;"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 1 0 immh#4 immb#3 opcode#5 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTZS <Vd>.<T>, <Vn>.<T>, #<fbits>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if immh == '0000' then SEE(asimdimm);",
"if immh == '000x' || (immh == '001x' && !HaveFP16Ext()) then ReservedValue();",
"if immh<3>:Q == '10' then ReservedValue();",
"integer esize = if immh == '1xxx' then 64 else if immh == '01xx' then 32 else 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"integer fracbits = (esize * 2) - UInt(immh:immb);",
"boolean unsigned = (U == '1');",
"FPRounding rounding = FPRounding_ZERO;"
]
}
],
"name": "FCVTZS (vector, fixed-point)",
"description": [
"Floating-point Convert to Signed fixed-point, rounding toward Zero (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"bits(datasize) result;",
"bits(esize) element;",
"",
"for e = 0 to elements-1",
" element = Elem[operand, e, esize];",
" Elem[result, e, esize] = FPToFixed(element, 0, unsigned, FPCR, rounding);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 0 o2#1 1 1 1 1 0 0 1 1 0 1 o1#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTZS <Hd>, <Hn>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = esize;",
"integer elements = 1;",
"",
"FPRounding rounding = FPDecodeRounding(o1:o2);",
"boolean unsigned = (U == '1');"
]
},
{
"pattern": "0 1 U#1 1 1 1 1 0 o2#1 sz#1 1 0 0 0 0 1 1 0 1 o1#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTZS <V><d>, <V><n>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 32 << UInt(sz);",
"integer datasize = esize;",
"integer elements = 1;",
"",
"FPRounding rounding = FPDecodeRounding(o1:o2);",
"boolean unsigned = (U == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o2#1 1 1 1 1 0 0 1 1 0 1 o1#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTZS <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"FPRounding rounding = FPDecodeRounding(o1:o2);",
"boolean unsigned = (U == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o2#1 sz#1 1 0 0 0 0 1 1 0 1 o1#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTZS <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"FPRounding rounding = FPDecodeRounding(o1:o2);",
"boolean unsigned = (U == '1');"
]
}
],
"name": "FCVTZS (vector, integer)",
"description": [
"Floating-point Convert to Signed integer, rounding toward Zero (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"",
"bits(fltsize) fltval;",
"bits(intsize) intval;",
"",
"case op of",
" when FPConvOp_CVT_FtoI",
" fltval = V[n];",
" intval = FPToFixed(fltval, fracbits, unsigned, FPCR, rounding);",
" X[d] = intval;",
" when FPConvOp_CVT_ItoF",
" intval = X[n];",
" fltval = FixedToFP(intval, fracbits, unsigned, FPCR, rounding);",
" V[d] = fltval;"
],
"variants": [
{
"pattern": "sf#1 0 S#1 1 1 1 1 0 type#2 0 rmode#2 opcode#3 scale#6 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0 && type == 11",
"format": "FCVTZS <Wd>, <Hn>, #<fbits>"
},
{
"condition": "sf == 1 && type == 11",
"format": "FCVTZS <Xd>, <Hn>, #<fbits>"
},
{
"condition": "sf == 0 && type == 00",
"format": "FCVTZS <Wd>, <Sn>, #<fbits>"
},
{
"condition": "sf == 1 && type == 00",
"format": "FCVTZS <Xd>, <Sn>, #<fbits>"
},
{
"condition": "sf == 0 && type == 01",
"format": "FCVTZS <Wd>, <Dn>, #<fbits>"
},
{
"condition": "sf == 1 && type == 01",
"format": "FCVTZS <Xd>, <Dn>, #<fbits>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer intsize = if sf == '1' then 64 else 32;",
"integer fltsize;",
"FPConvOp op;",
"FPRounding rounding;",
"boolean unsigned;",
"",
"case type of",
" when '00' fltsize = 32;",
" when '01' fltsize = 64;",
" when '10' UnallocatedEncoding();",
" when '11'",
" if HaveFP16Ext() then",
" fltsize = 16;",
" else",
" UnallocatedEncoding();",
"",
"if sf == '0' && scale<5> == '0' then UnallocatedEncoding();",
"integer fracbits = 64 - UInt(scale);",
"",
"case opcode<2:1>:rmode of",
" when '00 11' // FCVTZ",
" rounding = FPRounding_ZERO;",
" unsigned = (opcode<0> == '1');",
" op = FPConvOp_CVT_FtoI;",
" when '01 00' // [US]CVTF",
" rounding = FPRoundingMode(FPCR);",
" unsigned = (opcode<0> == '1');",
" op = FPConvOp_CVT_ItoF;",
" otherwise",
" UnallocatedEncoding();"
]
}
],
"name": "FCVTZS (scalar, fixed-point)",
"description": [
"Floating-point Convert to Signed fixed-point, rounding toward Zero (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"",
"bits(fltsize) fltval;",
"bits(intsize) intval;",
"",
"case op of",
" when FPConvOp_CVT_FtoI",
" fltval = V[n];",
" intval = FPToFixed(fltval, 0, unsigned, FPCR, rounding);",
" X[d] = intval;",
" when FPConvOp_CVT_ItoF",
" intval = X[n];",
" fltval = FixedToFP(intval, 0, unsigned, FPCR, rounding);",
" V[d] = fltval;",
" when FPConvOp_MOV_FtoI",
" fltval = Vpart[n,part];",
" intval = ZeroExtend(fltval, intsize);",
" X[d] = intval;",
" when FPConvOp_MOV_ItoF",
" intval = X[n];",
" fltval = intval;",
" Vpart[d,part] = fltval;"
],
"variants": [
{
"pattern": "sf#1 0 S#1 1 1 1 1 0 type#2 1 rmode#2 opcode#3 0 0 0 0 0 0 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0 && type == 11",
"format": "FCVTZS <Wd>, <Hn>"
},
{
"condition": "sf == 1 && type == 11",
"format": "FCVTZS <Xd>, <Hn>"
},
{
"condition": "sf == 0 && type == 00",
"format": "FCVTZS <Wd>, <Sn>"
},
{
"condition": "sf == 1 && type == 00",
"format": "FCVTZS <Xd>, <Sn>"
},
{
"condition": "sf == 0 && type == 01",
"format": "FCVTZS <Wd>, <Dn>"
},
{
"condition": "sf == 1 && type == 01",
"format": "FCVTZS <Xd>, <Dn>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer intsize = if sf == '1' then 64 else 32;",
"integer fltsize;",
"FPConvOp op;",
"FPRounding rounding;",
"boolean unsigned;",
"integer part;",
"",
"case type of",
" when '00'",
" fltsize = 32;",
" when '01' ",
" fltsize = 64;",
" when '10' ",
" if opcode<2:1>:rmode != '11 01' then UnallocatedEncoding();",
" fltsize = 128;",
" when '11' ",
" if HaveFP16Ext() then",
" fltsize = 16;",
" else",
" UnallocatedEncoding();",
"",
"case opcode<2:1>:rmode of",
" when '00 xx' // FCVT[NPMZ][US]",
" rounding = FPDecodeRounding(rmode);",
" unsigned = (opcode<0> == '1');",
" op = FPConvOp_CVT_FtoI;",
" when '01 00' // [US]CVTF",
" rounding = FPRoundingMode(FPCR);",
" unsigned = (opcode<0> == '1');",
" op = FPConvOp_CVT_ItoF;",
" when '10 00' // FCVTA[US]",
" rounding = FPRounding_TIEAWAY;",
" unsigned = (opcode<0> == '1');",
" op = FPConvOp_CVT_FtoI;",
" when '11 00' // FMOV",
" if fltsize != 16 && fltsize != intsize then UnallocatedEncoding();",
" op = if opcode<0> == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI;",
" part = 0;",
" when '11 01' // FMOV D[1]",
" if intsize != 64 || fltsize != 128 then UnallocatedEncoding();",
" op = if opcode<0> == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI;",
" part = 1;",
" fltsize = 64; // size of D[1] is 64",
" otherwise ",
" UnallocatedEncoding();"
]
}
],
"name": "FCVTZS (scalar, integer)",
"description": [
"Floating-point Convert to Signed integer, rounding toward Zero (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"bits(datasize) result;",
"bits(esize) element;",
"",
"for e = 0 to elements-1",
" element = Elem[operand, e, esize];",
" Elem[result, e, esize] = FPToFixed(element, fracbits, unsigned, FPCR, rounding);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 1 0 immh#4 immb#3 opcode#5 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTZU <V><d>, <V><n>, #<fbits>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if immh == '000x' || (immh == '001x' && !HaveFP16Ext()) then ReservedValue();",
"integer esize = if immh == '1xxx' then 64 else if immh == '01xx' then 32 else 16;",
"integer datasize = esize;",
"integer elements = 1;",
"",
"integer fracbits = (esize * 2) - UInt(immh:immb);",
"boolean unsigned = (U == '1');",
"FPRounding rounding = FPRounding_ZERO;"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 1 0 immh#4 immb#3 opcode#5 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTZU <Vd>.<T>, <Vn>.<T>, #<fbits>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if immh == '0000' then SEE(asimdimm);",
"if immh == '000x' || (immh == '001x' && !HaveFP16Ext()) then ReservedValue();",
"if immh<3>:Q == '10' then ReservedValue();",
"integer esize = if immh == '1xxx' then 64 else if immh == '01xx' then 32 else 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"integer fracbits = (esize * 2) - UInt(immh:immb);",
"boolean unsigned = (U == '1');",
"FPRounding rounding = FPRounding_ZERO;"
]
}
],
"name": "FCVTZU (vector, fixed-point)",
"description": [
"Floating-point Convert to Unsigned fixed-point, rounding toward Zero (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"bits(datasize) result;",
"bits(esize) element;",
"",
"for e = 0 to elements-1",
" element = Elem[operand, e, esize];",
" Elem[result, e, esize] = FPToFixed(element, 0, unsigned, FPCR, rounding);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 0 o2#1 1 1 1 1 0 0 1 1 0 1 o1#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTZU <Hd>, <Hn>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = esize;",
"integer elements = 1;",
"",
"FPRounding rounding = FPDecodeRounding(o1:o2);",
"boolean unsigned = (U == '1');"
]
},
{
"pattern": "0 1 U#1 1 1 1 1 0 o2#1 sz#1 1 0 0 0 0 1 1 0 1 o1#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTZU <V><d>, <V><n>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 32 << UInt(sz);",
"integer datasize = esize;",
"integer elements = 1;",
"",
"FPRounding rounding = FPDecodeRounding(o1:o2);",
"boolean unsigned = (U == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o2#1 1 1 1 1 0 0 1 1 0 1 o1#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTZU <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"FPRounding rounding = FPDecodeRounding(o1:o2);",
"boolean unsigned = (U == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o2#1 sz#1 1 0 0 0 0 1 1 0 1 o1#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FCVTZU <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"FPRounding rounding = FPDecodeRounding(o1:o2);",
"boolean unsigned = (U == '1');"
]
}
],
"name": "FCVTZU (vector, integer)",
"description": [
"Floating-point Convert to Unsigned integer, rounding toward Zero (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"",
"bits(fltsize) fltval;",
"bits(intsize) intval;",
"",
"case op of",
" when FPConvOp_CVT_FtoI",
" fltval = V[n];",
" intval = FPToFixed(fltval, fracbits, unsigned, FPCR, rounding);",
" X[d] = intval;",
" when FPConvOp_CVT_ItoF",
" intval = X[n];",
" fltval = FixedToFP(intval, fracbits, unsigned, FPCR, rounding);",
" V[d] = fltval;"
],
"variants": [
{
"pattern": "sf#1 0 S#1 1 1 1 1 0 type#2 0 rmode#2 opcode#3 scale#6 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0 && type == 11",
"format": "FCVTZU <Wd>, <Hn>, #<fbits>"
},
{
"condition": "sf == 1 && type == 11",
"format": "FCVTZU <Xd>, <Hn>, #<fbits>"
},
{
"condition": "sf == 0 && type == 00",
"format": "FCVTZU <Wd>, <Sn>, #<fbits>"
},
{
"condition": "sf == 1 && type == 00",
"format": "FCVTZU <Xd>, <Sn>, #<fbits>"
},
{
"condition": "sf == 0 && type == 01",
"format": "FCVTZU <Wd>, <Dn>, #<fbits>"
},
{
"condition": "sf == 1 && type == 01",
"format": "FCVTZU <Xd>, <Dn>, #<fbits>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer intsize = if sf == '1' then 64 else 32;",
"integer fltsize;",
"FPConvOp op;",
"FPRounding rounding;",
"boolean unsigned;",
"",
"case type of",
" when '00' fltsize = 32;",
" when '01' fltsize = 64;",
" when '10' UnallocatedEncoding();",
" when '11'",
" if HaveFP16Ext() then",
" fltsize = 16;",
" else",
" UnallocatedEncoding();",
"",
"if sf == '0' && scale<5> == '0' then UnallocatedEncoding();",
"integer fracbits = 64 - UInt(scale);",
"",
"case opcode<2:1>:rmode of",
" when '00 11' // FCVTZ",
" rounding = FPRounding_ZERO;",
" unsigned = (opcode<0> == '1');",
" op = FPConvOp_CVT_FtoI;",
" when '01 00' // [US]CVTF",
" rounding = FPRoundingMode(FPCR);",
" unsigned = (opcode<0> == '1');",
" op = FPConvOp_CVT_ItoF;",
" otherwise",
" UnallocatedEncoding();"
]
}
],
"name": "FCVTZU (scalar, fixed-point)",
"description": [
"Floating-point Convert to Unsigned fixed-point, rounding toward Zero (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"",
"bits(fltsize) fltval;",
"bits(intsize) intval;",
"",
"case op of",
" when FPConvOp_CVT_FtoI",
" fltval = V[n];",
" intval = FPToFixed(fltval, 0, unsigned, FPCR, rounding);",
" X[d] = intval;",
" when FPConvOp_CVT_ItoF",
" intval = X[n];",
" fltval = FixedToFP(intval, 0, unsigned, FPCR, rounding);",
" V[d] = fltval;",
" when FPConvOp_MOV_FtoI",
" fltval = Vpart[n,part];",
" intval = ZeroExtend(fltval, intsize);",
" X[d] = intval;",
" when FPConvOp_MOV_ItoF",
" intval = X[n];",
" fltval = intval;",
" Vpart[d,part] = fltval;"
],
"variants": [
{
"pattern": "sf#1 0 S#1 1 1 1 1 0 type#2 1 rmode#2 opcode#3 0 0 0 0 0 0 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0 && type == 11",
"format": "FCVTZU <Wd>, <Hn>"
},
{
"condition": "sf == 1 && type == 11",
"format": "FCVTZU <Xd>, <Hn>"
},
{
"condition": "sf == 0 && type == 00",
"format": "FCVTZU <Wd>, <Sn>"
},
{
"condition": "sf == 1 && type == 00",
"format": "FCVTZU <Xd>, <Sn>"
},
{
"condition": "sf == 0 && type == 01",
"format": "FCVTZU <Wd>, <Dn>"
},
{
"condition": "sf == 1 && type == 01",
"format": "FCVTZU <Xd>, <Dn>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer intsize = if sf == '1' then 64 else 32;",
"integer fltsize;",
"FPConvOp op;",
"FPRounding rounding;",
"boolean unsigned;",
"integer part;",
"",
"case type of",
" when '00'",
" fltsize = 32;",
" when '01' ",
" fltsize = 64;",
" when '10' ",
" if opcode<2:1>:rmode != '11 01' then UnallocatedEncoding();",
" fltsize = 128;",
" when '11' ",
" if HaveFP16Ext() then",
" fltsize = 16;",
" else",
" UnallocatedEncoding();",
"",
"case opcode<2:1>:rmode of",
" when '00 xx' // FCVT[NPMZ][US]",
" rounding = FPDecodeRounding(rmode);",
" unsigned = (opcode<0> == '1');",
" op = FPConvOp_CVT_FtoI;",
" when '01 00' // [US]CVTF",
" rounding = FPRoundingMode(FPCR);",
" unsigned = (opcode<0> == '1');",
" op = FPConvOp_CVT_ItoF;",
" when '10 00' // FCVTA[US]",
" rounding = FPRounding_TIEAWAY;",
" unsigned = (opcode<0> == '1');",
" op = FPConvOp_CVT_FtoI;",
" when '11 00' // FMOV",
" if fltsize != 16 && fltsize != intsize then UnallocatedEncoding();",
" op = if opcode<0> == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI;",
" part = 0;",
" when '11 01' // FMOV D[1]",
" if intsize != 64 || fltsize != 128 then UnallocatedEncoding();",
" op = if opcode<0> == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI;",
" part = 1;",
" fltsize = 64; // size of D[1] is 64",
" otherwise ",
" UnallocatedEncoding();"
]
}
],
"name": "FCVTZU (scalar, integer)",
"description": [
"Floating-point Convert to Unsigned integer, rounding toward Zero (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"bits(datasize) result;",
"bits(esize) element1;",
"bits(esize) element2;",
"",
"for e = 0 to elements-1",
" element1 = Elem[operand1, e, esize];",
" element2 = Elem[operand2, e, esize];",
" Elem[result, e, esize] = FPDiv(element1, element2, FPCR);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 a#1 1 0 Rm#5 0 0 opcode#3 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FDIV <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 0 sz#1 1 Rm#5 opcode#5 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FDIV <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;"
]
}
],
"name": "FDIV (vector)",
"description": [
"Floating-point Divide (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) result;",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"",
"result = FPDiv(operand1, operand2, FPCR);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "M#1 0 S#1 1 1 1 1 0 type#2 1 Rm#5 opcode#4 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": "type == 11",
"format": "FDIV <Hd>, <Hn>, <Hm>"
},
{
"condition": "type == 00",
"format": "FDIV <Sd>, <Sn>, <Sm>"
},
{
"condition": "type == 01",
"format": "FDIV <Dd>, <Dn>, <Dm>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"",
"integer datasize;",
"case type of",
" when '00' datasize = 32;",
" when '01' datasize = 64;",
" when '10' UnallocatedEncoding();",
" when '11'",
" if HaveFP16Ext() then",
" datasize = 16;",
" else",
" UnallocatedEncoding();"
]
}
],
"name": "FDIV (scalar)",
"description": [
"Floating-point Divide (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) result;",
"bits(datasize) operanda = V[a];",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"",
"if opa_neg then operanda = FPNeg(operanda);",
"if op1_neg then operand1 = FPNeg(operand1);",
"result = FPMulAdd(operanda, operand1, operand2, FPCR);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "M#1 0 S#1 1 1 1 1 1 type#2 o1#1 Rm#5 o0#1 Ra#5 Rn#5 Rd#5",
"formats": [
{
"condition": "type == 11",
"format": "FMADD <Hd>, <Hn>, <Hm>, <Ha>"
},
{
"condition": "type == 00",
"format": "FMADD <Sd>, <Sn>, <Sm>, <Sa>"
},
{
"condition": "type == 01",
"format": "FMADD <Dd>, <Dn>, <Dm>, <Da>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer a = UInt(Ra);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"",
"integer datasize;",
"case type of",
" when '00' datasize = 32;",
" when '01' datasize = 64;",
" when '10' UnallocatedEncoding();",
" when '11'",
" if HaveFP16Ext() then",
" datasize = 16;",
" else",
" UnallocatedEncoding();",
"",
"boolean opa_neg = (o1 == '1');",
"boolean op1_neg = (o0 != o1);"
]
}
],
"name": "FMADD",
"description": [
"Floating-point fused Multiply-Add (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"bits(datasize) result;",
"bits(2*datasize) concat = operand2:operand1;",
"bits(esize) element1;",
"bits(esize) element2;",
"",
"for e = 0 to elements-1",
" if pair then",
" element1 = Elem[concat, 2*e, esize];",
" element2 = Elem[concat, (2*e)+1, esize];",
" else",
" element1 = Elem[operand1, e, esize];",
" element2 = Elem[operand2, e, esize];",
"",
" if minimum then",
" Elem[result, e, esize] = FPMin(element1, element2, FPCR);",
" else",
" Elem[result, e, esize] = FPMax(element1, element2, FPCR);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o1#1 1 0 Rm#5 0 0 opcode#3 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMAX <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"boolean pair = (U == '1');",
"boolean minimum = (o1 == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o1#1 sz#1 1 Rm#5 opcode#5 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMAX <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"boolean pair = (U == '1');",
"boolean minimum = (o1 == '1');"
]
}
],
"name": "FMAX (vector)",
"description": [
"Floating-point Maximum (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) result;",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"",
"case operation of",
" when FPMaxMinOp_MAX result = FPMax(operand1, operand2, FPCR);",
" when FPMaxMinOp_MIN result = FPMin(operand1, operand2, FPCR);",
" when FPMaxMinOp_MAXNUM result = FPMaxNum(operand1, operand2, FPCR);",
" when FPMaxMinOp_MINNUM result = FPMinNum(operand1, operand2, FPCR);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "M#1 0 S#1 1 1 1 1 0 type#2 1 Rm#5 0 1 op#2 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": "type == 11",
"format": "FMAX <Hd>, <Hn>, <Hm>"
},
{
"condition": "type == 00",
"format": "FMAX <Sd>, <Sn>, <Sm>"
},
{
"condition": "type == 01",
"format": "FMAX <Dd>, <Dn>, <Dm>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"",
"integer datasize;",
"case type of",
" when '00' datasize = 32;",
" when '01' datasize = 64;",
" when '10' UnallocatedEncoding();",
" when '11'",
" if HaveFP16Ext() then",
" datasize = 16;",
" else",
" UnallocatedEncoding();",
"",
"FPMaxMinOp operation;",
"case op of",
" when '00' operation = FPMaxMinOp_MAX;",
" when '01' operation = FPMaxMinOp_MIN;",
" when '10' operation = FPMaxMinOp_MAXNUM;",
" when '11' operation = FPMaxMinOp_MINNUM;"
]
}
],
"name": "FMAX (scalar)",
"description": [
"Floating-point Maximum (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"bits(datasize) result;",
"bits(2*datasize) concat = operand2:operand1;",
"bits(esize) element1;",
"bits(esize) element2;",
"",
"for e = 0 to elements-1",
" if pair then",
" element1 = Elem[concat, 2*e, esize];",
" element2 = Elem[concat, (2*e)+1, esize];",
" else",
" element1 = Elem[operand1, e, esize];",
" element2 = Elem[operand2, e, esize];",
"",
" if minimum then",
" Elem[result, e, esize] = FPMinNum(element1, element2, FPCR);",
" else",
" Elem[result, e, esize] = FPMaxNum(element1, element2, FPCR);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 a#1 1 0 Rm#5 0 0 Op3#3 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMAXNM <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"boolean pair = (U == '1');",
"boolean minimum = (a == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o1#1 sz#1 1 Rm#5 opcode#5 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMAXNM <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"boolean pair = (U == '1');",
"boolean minimum = (o1 == '1');"
]
}
],
"name": "FMAXNM (vector)",
"description": [
"Floating-point Maximum Number (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) result;",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"",
"case operation of",
" when FPMaxMinOp_MAX result = FPMax(operand1, operand2, FPCR);",
" when FPMaxMinOp_MIN result = FPMin(operand1, operand2, FPCR);",
" when FPMaxMinOp_MAXNUM result = FPMaxNum(operand1, operand2, FPCR);",
" when FPMaxMinOp_MINNUM result = FPMinNum(operand1, operand2, FPCR);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "M#1 0 S#1 1 1 1 1 0 type#2 1 Rm#5 0 1 op#2 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": "type == 11",
"format": "FMAXNM <Hd>, <Hn>, <Hm>"
},
{
"condition": "type == 00",
"format": "FMAXNM <Sd>, <Sn>, <Sm>"
},
{
"condition": "type == 01",
"format": "FMAXNM <Dd>, <Dn>, <Dm>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"",
"integer datasize;",
"case type of",
" when '00' datasize = 32;",
" when '01' datasize = 64;",
" when '10' UnallocatedEncoding();",
" when '11'",
" if HaveFP16Ext() then",
" datasize = 16;",
" else",
" UnallocatedEncoding();",
"",
"FPMaxMinOp operation;",
"case op of",
" when '00' operation = FPMaxMinOp_MAX;",
" when '01' operation = FPMaxMinOp_MIN;",
" when '10' operation = FPMaxMinOp_MAXNUM;",
" when '11' operation = FPMaxMinOp_MINNUM;"
]
}
],
"name": "FMAXNM (scalar)",
"description": [
"Floating-point Maximum Number (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"V[d] = Reduce(op, operand, esize);"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 0 o1#1 sz#1 1 1 0 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMAXNMP <V><d>, <Vn>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"if sz == '1' then ReservedValue();",
"integer datasize = esize * 2;",
"integer elements = 2;",
"",
"ReduceOp op = if o1 == '1' then ReduceOp_FMINNUM else ReduceOp_FMAXNUM;"
]
},
{
"pattern": "0 1 U#1 1 1 1 1 0 o1#1 sz#1 1 1 0 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMAXNMP <V><d>, <Vn>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 32 << UInt(sz);",
"integer datasize = esize * 2;",
"integer elements = 2;",
"",
"ReduceOp op = if o1 == '1' then ReduceOp_FMINNUM else ReduceOp_FMAXNUM;"
]
}
],
"name": "FMAXNMP (scalar)",
"description": [
"Floating-point Maximum Number of Pair of elements (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"bits(datasize) result;",
"bits(2*datasize) concat = operand2:operand1;",
"bits(esize) element1;",
"bits(esize) element2;",
"",
"for e = 0 to elements-1",
" if pair then",
" element1 = Elem[concat, 2*e, esize];",
" element2 = Elem[concat, (2*e)+1, esize];",
" else",
" element1 = Elem[operand1, e, esize];",
" element2 = Elem[operand2, e, esize];",
"",
" if minimum then",
" Elem[result, e, esize] = FPMinNum(element1, element2, FPCR);",
" else",
" Elem[result, e, esize] = FPMaxNum(element1, element2, FPCR);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 a#1 1 0 Rm#5 0 0 Op3#3 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMAXNMP <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"boolean pair = (U == '1');",
"boolean minimum = (a == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o1#1 sz#1 1 Rm#5 opcode#5 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMAXNMP <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"boolean pair = (U == '1');",
"boolean minimum = (o1 == '1');"
]
}
],
"name": "FMAXNMP (vector)",
"description": [
"Floating-point Maximum Number Pairwise (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"V[d] = Reduce(op, operand, esize);"
],
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o1#1 0 1 1 0 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMAXNMV <V><d>, <Vn>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"ReduceOp op = if o1 == '1' then ReduceOp_FMINNUM else ReduceOp_FMAXNUM;"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o1#1 sz#1 1 1 0 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMAXNMV <V><d>, <Vn>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if sz:Q != '01' then ReservedValue(); // .4S only",
"",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"ReduceOp op = if o1 == '1' then ReduceOp_FMINNUM else ReduceOp_FMAXNUM;"
]
}
],
"name": "FMAXNMV",
"description": [
"Floating-point Maximum Number across Vector"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"V[d] = Reduce(op, operand, esize);"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 0 o1#1 sz#1 1 1 0 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMAXP <V><d>, <Vn>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"if sz == '1' then ReservedValue();",
"integer datasize = esize * 2;",
"integer elements = 2;",
"",
"ReduceOp op = if o1 == '1' then ReduceOp_FMIN else ReduceOp_FMAX;"
]
},
{
"pattern": "0 1 U#1 1 1 1 1 0 o1#1 sz#1 1 1 0 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMAXP <V><d>, <Vn>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 32 << UInt(sz);",
"integer datasize = esize * 2;",
"integer elements = 2;",
"",
"ReduceOp op = if o1 == '1' then ReduceOp_FMIN else ReduceOp_FMAX;"
]
}
],
"name": "FMAXP (scalar)",
"description": [
"Floating-point Maximum of Pair of elements (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"bits(datasize) result;",
"bits(2*datasize) concat = operand2:operand1;",
"bits(esize) element1;",
"bits(esize) element2;",
"",
"for e = 0 to elements-1",
" if pair then",
" element1 = Elem[concat, 2*e, esize];",
" element2 = Elem[concat, (2*e)+1, esize];",
" else",
" element1 = Elem[operand1, e, esize];",
" element2 = Elem[operand2, e, esize];",
"",
" if minimum then",
" Elem[result, e, esize] = FPMin(element1, element2, FPCR);",
" else",
" Elem[result, e, esize] = FPMax(element1, element2, FPCR);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o1#1 1 0 Rm#5 0 0 opcode#3 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMAXP <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"boolean pair = (U == '1');",
"boolean minimum = (o1 == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o1#1 sz#1 1 Rm#5 opcode#5 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMAXP <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"boolean pair = (U == '1');",
"boolean minimum = (o1 == '1');"
]
}
],
"name": "FMAXP (vector)",
"description": [
"Floating-point Maximum Pairwise (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"V[d] = Reduce(op, operand, esize);"
],
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o1#1 0 1 1 0 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMAXV <V><d>, <Vn>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"ReduceOp op = if o1 == '1' then ReduceOp_FMIN else ReduceOp_FMAX;"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o1#1 sz#1 1 1 0 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMAXV <V><d>, <Vn>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if sz:Q != '01' then ReservedValue();",
"",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"ReduceOp op = if o1 == '1' then ReduceOp_FMIN else ReduceOp_FMAX;"
]
}
],
"name": "FMAXV",
"description": [
"Floating-point Maximum across Vector"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"bits(datasize) result;",
"bits(2*datasize) concat = operand2:operand1;",
"bits(esize) element1;",
"bits(esize) element2;",
"",
"for e = 0 to elements-1",
" if pair then",
" element1 = Elem[concat, 2*e, esize];",
" element2 = Elem[concat, (2*e)+1, esize];",
" else",
" element1 = Elem[operand1, e, esize];",
" element2 = Elem[operand2, e, esize];",
"",
" if minimum then",
" Elem[result, e, esize] = FPMin(element1, element2, FPCR);",
" else",
" Elem[result, e, esize] = FPMax(element1, element2, FPCR);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o1#1 1 0 Rm#5 0 0 opcode#3 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMIN <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"boolean pair = (U == '1');",
"boolean minimum = (o1 == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o1#1 sz#1 1 Rm#5 opcode#5 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMIN <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"boolean pair = (U == '1');",
"boolean minimum = (o1 == '1');"
]
}
],
"name": "FMIN (vector)",
"description": [
"Floating-point minimum (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) result;",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"",
"case operation of",
" when FPMaxMinOp_MAX result = FPMax(operand1, operand2, FPCR);",
" when FPMaxMinOp_MIN result = FPMin(operand1, operand2, FPCR);",
" when FPMaxMinOp_MAXNUM result = FPMaxNum(operand1, operand2, FPCR);",
" when FPMaxMinOp_MINNUM result = FPMinNum(operand1, operand2, FPCR);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "M#1 0 S#1 1 1 1 1 0 type#2 1 Rm#5 0 1 op#2 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": "type == 11",
"format": "FMIN <Hd>, <Hn>, <Hm>"
},
{
"condition": "type == 00",
"format": "FMIN <Sd>, <Sn>, <Sm>"
},
{
"condition": "type == 01",
"format": "FMIN <Dd>, <Dn>, <Dm>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"",
"integer datasize;",
"case type of",
" when '00' datasize = 32;",
" when '01' datasize = 64;",
" when '10' UnallocatedEncoding();",
" when '11'",
" if HaveFP16Ext() then",
" datasize = 16;",
" else",
" UnallocatedEncoding();",
"",
"FPMaxMinOp operation;",
"case op of",
" when '00' operation = FPMaxMinOp_MAX;",
" when '01' operation = FPMaxMinOp_MIN;",
" when '10' operation = FPMaxMinOp_MAXNUM;",
" when '11' operation = FPMaxMinOp_MINNUM;"
]
}
],
"name": "FMIN (scalar)",
"description": [
"Floating-point Minimum (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"bits(datasize) result;",
"bits(2*datasize) concat = operand2:operand1;",
"bits(esize) element1;",
"bits(esize) element2;",
"",
"for e = 0 to elements-1",
" if pair then",
" element1 = Elem[concat, 2*e, esize];",
" element2 = Elem[concat, (2*e)+1, esize];",
" else",
" element1 = Elem[operand1, e, esize];",
" element2 = Elem[operand2, e, esize];",
"",
" if minimum then",
" Elem[result, e, esize] = FPMinNum(element1, element2, FPCR);",
" else",
" Elem[result, e, esize] = FPMaxNum(element1, element2, FPCR);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 a#1 1 0 Rm#5 0 0 Op3#3 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMINNM <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"boolean pair = (U == '1');",
"boolean minimum = (a == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o1#1 sz#1 1 Rm#5 opcode#5 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMINNM <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"boolean pair = (U == '1');",
"boolean minimum = (o1 == '1');"
]
}
],
"name": "FMINNM (vector)",
"description": [
"Floating-point Minimum Number (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) result;",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"",
"case operation of",
" when FPMaxMinOp_MAX result = FPMax(operand1, operand2, FPCR);",
" when FPMaxMinOp_MIN result = FPMin(operand1, operand2, FPCR);",
" when FPMaxMinOp_MAXNUM result = FPMaxNum(operand1, operand2, FPCR);",
" when FPMaxMinOp_MINNUM result = FPMinNum(operand1, operand2, FPCR);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "M#1 0 S#1 1 1 1 1 0 type#2 1 Rm#5 0 1 op#2 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": "type == 11",
"format": "FMINNM <Hd>, <Hn>, <Hm>"
},
{
"condition": "type == 00",
"format": "FMINNM <Sd>, <Sn>, <Sm>"
},
{
"condition": "type == 01",
"format": "FMINNM <Dd>, <Dn>, <Dm>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"",
"integer datasize;",
"case type of",
" when '00' datasize = 32;",
" when '01' datasize = 64;",
" when '10' UnallocatedEncoding();",
" when '11'",
" if HaveFP16Ext() then",
" datasize = 16;",
" else",
" UnallocatedEncoding();",
"",
"FPMaxMinOp operation;",
"case op of",
" when '00' operation = FPMaxMinOp_MAX;",
" when '01' operation = FPMaxMinOp_MIN;",
" when '10' operation = FPMaxMinOp_MAXNUM;",
" when '11' operation = FPMaxMinOp_MINNUM;"
]
}
],
"name": "FMINNM (scalar)",
"description": [
"Floating-point Minimum Number (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"V[d] = Reduce(op, operand, esize);"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 0 o1#1 sz#1 1 1 0 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMINNMP <V><d>, <Vn>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"if sz == '1' then ReservedValue();",
"integer datasize = esize * 2;",
"integer elements = 2;",
"",
"ReduceOp op = if o1 == '1' then ReduceOp_FMINNUM else ReduceOp_FMAXNUM;"
]
},
{
"pattern": "0 1 U#1 1 1 1 1 0 o1#1 sz#1 1 1 0 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMINNMP <V><d>, <Vn>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 32 << UInt(sz);",
"integer datasize = esize * 2;",
"integer elements = 2;",
"",
"ReduceOp op = if o1 == '1' then ReduceOp_FMINNUM else ReduceOp_FMAXNUM;"
]
}
],
"name": "FMINNMP (scalar)",
"description": [
"Floating-point Minimum Number of Pair of elements (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"bits(datasize) result;",
"bits(2*datasize) concat = operand2:operand1;",
"bits(esize) element1;",
"bits(esize) element2;",
"",
"for e = 0 to elements-1",
" if pair then",
" element1 = Elem[concat, 2*e, esize];",
" element2 = Elem[concat, (2*e)+1, esize];",
" else",
" element1 = Elem[operand1, e, esize];",
" element2 = Elem[operand2, e, esize];",
"",
" if minimum then",
" Elem[result, e, esize] = FPMinNum(element1, element2, FPCR);",
" else",
" Elem[result, e, esize] = FPMaxNum(element1, element2, FPCR);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 a#1 1 0 Rm#5 0 0 Op3#3 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMINNMP <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"boolean pair = (U == '1');",
"boolean minimum = (a == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o1#1 sz#1 1 Rm#5 opcode#5 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMINNMP <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"boolean pair = (U == '1');",
"boolean minimum = (o1 == '1');"
]
}
],
"name": "FMINNMP (vector)",
"description": [
"Floating-point Minimum Number Pairwise (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"V[d] = Reduce(op, operand, esize);"
],
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o1#1 0 1 1 0 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMINNMV <V><d>, <Vn>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"ReduceOp op = if o1 == '1' then ReduceOp_FMINNUM else ReduceOp_FMAXNUM;"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o1#1 sz#1 1 1 0 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMINNMV <V><d>, <Vn>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if sz:Q != '01' then ReservedValue(); // .4S only",
"",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"ReduceOp op = if o1 == '1' then ReduceOp_FMINNUM else ReduceOp_FMAXNUM;"
]
}
],
"name": "FMINNMV",
"description": [
"Floating-point Minimum Number across Vector"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"V[d] = Reduce(op, operand, esize);"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 0 o1#1 sz#1 1 1 0 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMINP <V><d>, <Vn>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"if sz == '1' then ReservedValue();",
"integer datasize = esize * 2;",
"integer elements = 2;",
"",
"ReduceOp op = if o1 == '1' then ReduceOp_FMIN else ReduceOp_FMAX;"
]
},
{
"pattern": "0 1 U#1 1 1 1 1 0 o1#1 sz#1 1 1 0 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMINP <V><d>, <Vn>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 32 << UInt(sz);",
"integer datasize = esize * 2;",
"integer elements = 2;",
"",
"ReduceOp op = if o1 == '1' then ReduceOp_FMIN else ReduceOp_FMAX;"
]
}
],
"name": "FMINP (scalar)",
"description": [
"Floating-point Minimum of Pair of elements (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"bits(datasize) result;",
"bits(2*datasize) concat = operand2:operand1;",
"bits(esize) element1;",
"bits(esize) element2;",
"",
"for e = 0 to elements-1",
" if pair then",
" element1 = Elem[concat, 2*e, esize];",
" element2 = Elem[concat, (2*e)+1, esize];",
" else",
" element1 = Elem[operand1, e, esize];",
" element2 = Elem[operand2, e, esize];",
"",
" if minimum then",
" Elem[result, e, esize] = FPMin(element1, element2, FPCR);",
" else",
" Elem[result, e, esize] = FPMax(element1, element2, FPCR);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o1#1 1 0 Rm#5 0 0 opcode#3 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMINP <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"boolean pair = (U == '1');",
"boolean minimum = (o1 == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o1#1 sz#1 1 Rm#5 opcode#5 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMINP <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"boolean pair = (U == '1');",
"boolean minimum = (o1 == '1');"
]
}
],
"name": "FMINP (vector)",
"description": [
"Floating-point Minimum Pairwise (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"V[d] = Reduce(op, operand, esize);"
],
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o1#1 0 1 1 0 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMINV <V><d>, <Vn>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"ReduceOp op = if o1 == '1' then ReduceOp_FMIN else ReduceOp_FMAX;"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o1#1 sz#1 1 1 0 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMINV <V><d>, <Vn>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if sz:Q != '01' then ReservedValue();",
"",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"ReduceOp op = if o1 == '1' then ReduceOp_FMIN else ReduceOp_FMAX;"
]
}
],
"name": "FMINV",
"description": [
"Floating-point Minimum across Vector"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand1 = V[n];",
"bits(idxdsize) operand2 = V[m];",
"bits(datasize) operand3 = V[d];",
"bits(datasize) result;",
"bits(esize) element1;",
"bits(esize) element2 = Elem[operand2, index, esize];",
"",
"for e = 0 to elements-1",
" element1 = Elem[operand1, e, esize];",
" if sub_op then element1 = FPNeg(element1);",
" Elem[result, e, esize] = FPMulAdd(Elem[operand3, e, esize], element1, element2, FPCR);",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 1 size#2 L#1 M#1 Rm#4 0 o2#1 0 1 H#1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMLA <Hd>, <Hn>, <Vm>.H[<index>]"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer idxdsize = if H == '1' then 128 else 64;",
"integer index;",
"index = UInt(H:L:M);",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"",
"integer esize = 16;",
"integer datasize = esize;",
"integer elements = 1;",
"boolean sub_op = (o2 == '1');"
]
},
{
"pattern": "0 1 U#1 1 1 1 1 1 1 sz#1 L#1 M#1 Rm#4 0 o2#1 0 1 H#1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMLA <V><d>, <V><n>, <Vm>.<Ts>[<index>]"
}
],
"decoder": [
"integer idxdsize = if H == '1' then 128 else 64; ",
"integer index;",
"bit Rmhi = M;",
"case sz:L of",
" when '0x' index = UInt(H:L);",
" when '10' index = UInt(H);",
" when '11' UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rmhi:Rm);",
"",
"integer esize = 32 << UInt(sz);",
"integer datasize = esize;",
"integer elements = 1;",
"boolean sub_op = (o2 == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 1 size#2 L#1 M#1 Rm#4 0 o2#1 0 1 H#1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMLA <Vd>.<T>, <Vn>.<T>, <Vm>.H[<index>]"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer idxdsize = if H == '1' then 128 else 64;",
"integer index;",
"index = UInt(H:L:M);",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"boolean sub_op = (o2 == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 1 1 sz#1 L#1 M#1 Rm#4 0 o2#1 0 1 H#1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMLA <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>]"
}
],
"decoder": [
"integer idxdsize = if H == '1' then 128 else 64; ",
"integer index;",
"bit Rmhi = M;",
"case sz:L of",
" when '0x' index = UInt(H:L);",
" when '10' index = UInt(H);",
" when '11' UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rmhi:Rm);",
"",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"boolean sub_op = (o2 == '1');"
]
}
],
"name": "FMLA (by element)",
"description": [
"Floating-point fused Multiply-Add to accumulator (by element)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"bits(datasize) operand3 = V[d];",
"bits(datasize) result;",
"bits(esize) element1;",
"bits(esize) element2;",
"",
"for e = 0 to elements-1",
" element1 = Elem[operand1, e, esize];",
" element2 = Elem[operand2, e, esize];",
" if sub_op then element1 = FPNeg(element1);",
" Elem[result, e, esize] = FPMulAdd(Elem[operand3, e, esize], element1, element2, FPCR);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 a#1 1 0 Rm#5 0 0 opcode#3 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMLA <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"boolean sub_op = (a == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 op#1 sz#1 1 Rm#5 opcode#5 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMLA <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"boolean sub_op = (op == '1');"
]
}
],
"name": "FMLA (vector)",
"description": [
"Floating-point fused Multiply-Add to accumulator (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand1 = V[n];",
"bits(idxdsize) operand2 = V[m];",
"bits(datasize) operand3 = V[d];",
"bits(datasize) result;",
"bits(esize) element1;",
"bits(esize) element2 = Elem[operand2, index, esize];",
"",
"for e = 0 to elements-1",
" element1 = Elem[operand1, e, esize];",
" if sub_op then element1 = FPNeg(element1);",
" Elem[result, e, esize] = FPMulAdd(Elem[operand3, e, esize], element1, element2, FPCR);",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 1 size#2 L#1 M#1 Rm#4 0 o2#1 0 1 H#1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMLS <Hd>, <Hn>, <Vm>.H[<index>]"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer idxdsize = if H == '1' then 128 else 64;",
"integer index;",
"index = UInt(H:L:M);",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"",
"integer esize = 16;",
"integer datasize = esize;",
"integer elements = 1;",
"boolean sub_op = (o2 == '1');"
]
},
{
"pattern": "0 1 U#1 1 1 1 1 1 1 sz#1 L#1 M#1 Rm#4 0 o2#1 0 1 H#1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMLS <V><d>, <V><n>, <Vm>.<Ts>[<index>]"
}
],
"decoder": [
"integer idxdsize = if H == '1' then 128 else 64; ",
"integer index;",
"bit Rmhi = M;",
"case sz:L of",
" when '0x' index = UInt(H:L);",
" when '10' index = UInt(H);",
" when '11' UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rmhi:Rm);",
"",
"integer esize = 32 << UInt(sz);",
"integer datasize = esize;",
"integer elements = 1;",
"boolean sub_op = (o2 == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 1 size#2 L#1 M#1 Rm#4 0 o2#1 0 1 H#1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMLS <Vd>.<T>, <Vn>.<T>, <Vm>.H[<index>]"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer idxdsize = if H == '1' then 128 else 64;",
"integer index;",
"index = UInt(H:L:M);",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"boolean sub_op = (o2 == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 1 1 sz#1 L#1 M#1 Rm#4 0 o2#1 0 1 H#1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMLS <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>]"
}
],
"decoder": [
"integer idxdsize = if H == '1' then 128 else 64; ",
"integer index;",
"bit Rmhi = M;",
"case sz:L of",
" when '0x' index = UInt(H:L);",
" when '10' index = UInt(H);",
" when '11' UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rmhi:Rm);",
"",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"boolean sub_op = (o2 == '1');"
]
}
],
"name": "FMLS (by element)",
"description": [
"Floating-point fused Multiply-Subtract from accumulator (by element)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"bits(datasize) operand3 = V[d];",
"bits(datasize) result;",
"bits(esize) element1;",
"bits(esize) element2;",
"",
"for e = 0 to elements-1",
" element1 = Elem[operand1, e, esize];",
" element2 = Elem[operand2, e, esize];",
" if sub_op then element1 = FPNeg(element1);",
" Elem[result, e, esize] = FPMulAdd(Elem[operand3, e, esize], element1, element2, FPCR);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 a#1 1 0 Rm#5 0 0 opcode#3 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMLS <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"boolean sub_op = (a == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 op#1 sz#1 1 Rm#5 opcode#5 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMLS <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"boolean sub_op = (op == '1');"
]
}
],
"name": "FMLS (vector)",
"description": [
"Floating-point fused Multiply-Subtract from accumulator (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"",
"V[rd] = imm;"
],
"variants": [
{
"pattern": "0 Q#1 op#1 0 1 1 1 1 0 0 0 0 0 a#1 b#1 c#1 cmode#4 o2#1 1 d#1 e#1 f#1 g#1 h#1 Rd#5",
"formats": [
{
"condition": null,
"format": "FMOV <Vd>.<T>, #<imm>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer rd = UInt(Rd);",
"",
"integer datasize = if Q == '1' then 128 else 64;",
"bits(datasize) imm;",
"",
"imm8 = a:b:c:d:e:f:g:h;",
"imm16 = imm8<7>:NOT(imm8<6>):Replicate(imm8<6>,2):imm8<5:0>:Zeros(6);",
"",
"imm = Replicate(imm16, datasize DIV 16);"
]
},
{
"pattern": "0 Q#1 op#1 0 1 1 1 1 0 0 0 0 0 a#1 b#1 c#1 cmode#4 o2#1 1 d#1 e#1 f#1 g#1 h#1 Rd#5",
"formats": [
{
"condition": "op == 0",
"format": "FMOV <Vd>.<T>, #<imm>"
},
{
"condition": "Q == 1 && op == 1",
"format": "FMOV <Vd>.2D, #<imm>"
}
],
"decoder": [
"integer rd = UInt(Rd);",
"",
"integer datasize = if Q == '1' then 128 else 64;",
"bits(datasize) imm;",
"bits(64) imm64;",
"",
"ImmediateOp operation;",
"case cmode:op of",
" when '0xx00' operation = ImmediateOp_MOVI;",
" when '0xx01' operation = ImmediateOp_MVNI;",
" when '0xx10' operation = ImmediateOp_ORR;",
" when '0xx11' operation = ImmediateOp_BIC;",
" when '10x00' operation = ImmediateOp_MOVI;",
" when '10x01' operation = ImmediateOp_MVNI;",
" when '10x10' operation = ImmediateOp_ORR;",
" when '10x11' operation = ImmediateOp_BIC;",
" when '110x0' operation = ImmediateOp_MOVI;",
" when '110x1' operation = ImmediateOp_MVNI;",
" when '1110x' operation = ImmediateOp_MOVI;",
" when '11110' operation = ImmediateOp_MOVI;",
" when '11111' ",
" // FMOV Dn,#imm is in main FP instruction set",
" if Q == '0' then UnallocatedEncoding();",
" operation = ImmediateOp_MOVI;",
"",
"imm64 = AdvSIMDExpandImm(op, cmode, a:b:c:d:e:f:g:h);",
"imm = Replicate(imm64, datasize DIV 64);"
]
}
],
"name": "FMOV (vector, immediate)",
"description": [
"Floating-point move immediate (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"",
"bits(datasize) result;",
"bits(datasize) operand = V[n];",
"",
"case fpop of",
" when FPUnaryOp_MOV result = operand;",
" when FPUnaryOp_ABS result = FPAbs(operand);",
" when FPUnaryOp_NEG result = FPNeg(operand);",
" when FPUnaryOp_SQRT result = FPSqrt(operand, FPCR);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "M#1 0 S#1 1 1 1 1 0 type#2 1 0 0 0 0 opc#2 1 0 0 0 0 Rn#5 Rd#5",
"formats": [
{
"condition": "type == 11",
"format": "FMOV <Hd>, <Hn>"
},
{
"condition": "type == 00",
"format": "FMOV <Sd>, <Sn>"
},
{
"condition": "type == 01",
"format": "FMOV <Dd>, <Dn>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer datasize;",
"case type of",
" when '00' datasize = 32;",
" when '01' datasize = 64;",
" when '10' UnallocatedEncoding();",
" when '11'",
" if HaveFP16Ext() then",
" datasize = 16;",
" else",
" UnallocatedEncoding();",
"",
"FPUnaryOp fpop;",
"case opc of",
" when '00' fpop = FPUnaryOp_MOV;",
" when '01' fpop = FPUnaryOp_ABS;",
" when '10' fpop = FPUnaryOp_NEG;",
" when '11' fpop = FPUnaryOp_SQRT;"
]
}
],
"name": "FMOV (register)",
"description": [
"Floating-point Move register without conversion"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"",
"bits(fltsize) fltval;",
"bits(intsize) intval;",
"",
"case op of",
" when FPConvOp_CVT_FtoI",
" fltval = V[n];",
" intval = FPToFixed(fltval, 0, unsigned, FPCR, rounding);",
" X[d] = intval;",
" when FPConvOp_CVT_ItoF",
" intval = X[n];",
" fltval = FixedToFP(intval, 0, unsigned, FPCR, rounding);",
" V[d] = fltval;",
" when FPConvOp_MOV_FtoI",
" fltval = Vpart[n,part];",
" intval = ZeroExtend(fltval, intsize);",
" X[d] = intval;",
" when FPConvOp_MOV_ItoF",
" intval = X[n];",
" fltval = intval;",
" Vpart[d,part] = fltval;"
],
"variants": [
{
"pattern": "sf#1 0 S#1 1 1 1 1 0 type#2 1 rmode#2 opcode#3 0 0 0 0 0 0 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0 && type == 11 && rmode == 00 && opcode == 110",
"format": "FMOV <Wd>, <Hn>"
},
{
"condition": "sf == 1 && type == 11 && rmode == 00 && opcode == 110",
"format": "FMOV <Xd>, <Hn>"
},
{
"condition": "sf == 0 && type == 11 && rmode == 00 && opcode == 111",
"format": "FMOV <Hd>, <Wn>"
},
{
"condition": "sf == 0 && type == 00 && rmode == 00 && opcode == 111",
"format": "FMOV <Sd>, <Wn>"
},
{
"condition": "sf == 0 && type == 00 && rmode == 00 && opcode == 110",
"format": "FMOV <Wd>, <Sn>"
},
{
"condition": "sf == 1 && type == 11 && rmode == 00 && opcode == 111",
"format": "FMOV <Hd>, <Xn>"
},
{
"condition": "sf == 1 && type == 01 && rmode == 00 && opcode == 111",
"format": "FMOV <Dd>, <Xn>"
},
{
"condition": "sf == 1 && type == 10 && rmode == 01 && opcode == 111",
"format": "FMOV <Vd>.D[1], <Xn>"
},
{
"condition": "sf == 1 && type == 01 && rmode == 00 && opcode == 110",
"format": "FMOV <Xd>, <Dn>"
},
{
"condition": "sf == 1 && type == 10 && rmode == 01 && opcode == 110",
"format": "FMOV <Xd>, <Vn>.D[1]"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer intsize = if sf == '1' then 64 else 32;",
"integer fltsize;",
"FPConvOp op;",
"FPRounding rounding;",
"boolean unsigned;",
"integer part;",
"",
"case type of",
" when '00'",
" fltsize = 32;",
" when '01' ",
" fltsize = 64;",
" when '10' ",
" if opcode<2:1>:rmode != '11 01' then UnallocatedEncoding();",
" fltsize = 128;",
" when '11' ",
" if HaveFP16Ext() then",
" fltsize = 16;",
" else",
" UnallocatedEncoding();",
"",
"case opcode<2:1>:rmode of",
" when '00 xx' // FCVT[NPMZ][US]",
" rounding = FPDecodeRounding(rmode);",
" unsigned = (opcode<0> == '1');",
" op = FPConvOp_CVT_FtoI;",
" when '01 00' // [US]CVTF",
" rounding = FPRoundingMode(FPCR);",
" unsigned = (opcode<0> == '1');",
" op = FPConvOp_CVT_ItoF;",
" when '10 00' // FCVTA[US]",
" rounding = FPRounding_TIEAWAY;",
" unsigned = (opcode<0> == '1');",
" op = FPConvOp_CVT_FtoI;",
" when '11 00' // FMOV",
" if fltsize != 16 && fltsize != intsize then UnallocatedEncoding();",
" op = if opcode<0> == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI;",
" part = 0;",
" when '11 01' // FMOV D[1]",
" if intsize != 64 || fltsize != 128 then UnallocatedEncoding();",
" op = if opcode<0> == '1' then FPConvOp_MOV_ItoF else FPConvOp_MOV_FtoI;",
" part = 1;",
" fltsize = 64; // size of D[1] is 64",
" otherwise ",
" UnallocatedEncoding();"
]
}
],
"name": "FMOV (general)",
"description": [
"Floating-point Move to or from general-purpose register without conversion"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"",
"V[d] = imm;"
],
"variants": [
{
"pattern": "M#1 0 S#1 1 1 1 1 0 type#2 1 imm8#8 1 0 0 imm5#5 Rd#5",
"formats": [
{
"condition": "type == 11",
"format": "FMOV <Hd>, #<imm>"
},
{
"condition": "type == 00",
"format": "FMOV <Sd>, #<imm>"
},
{
"condition": "type == 01",
"format": "FMOV <Dd>, #<imm>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"",
"integer datasize;",
"case type of",
" when '00' datasize = 32;",
" when '01' datasize = 64;",
" when '10' UnallocatedEncoding();",
" when '11'",
" if HaveFP16Ext() then",
" datasize = 16;",
" else",
" UnallocatedEncoding();",
"",
"bits(datasize) imm = VFPExpandImm(imm8);"
]
}
],
"name": "FMOV (scalar, immediate)",
"description": [
"Floating-point move immediate (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) result;",
"bits(datasize) operanda = V[a];",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"",
"if opa_neg then operanda = FPNeg(operanda);",
"if op1_neg then operand1 = FPNeg(operand1);",
"result = FPMulAdd(operanda, operand1, operand2, FPCR);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "M#1 0 S#1 1 1 1 1 1 type#2 o1#1 Rm#5 o0#1 Ra#5 Rn#5 Rd#5",
"formats": [
{
"condition": "type == 11",
"format": "FMSUB <Hd>, <Hn>, <Hm>, <Ha>"
},
{
"condition": "type == 00",
"format": "FMSUB <Sd>, <Sn>, <Sm>, <Sa>"
},
{
"condition": "type == 01",
"format": "FMSUB <Dd>, <Dn>, <Dm>, <Da>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer a = UInt(Ra);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"",
"integer datasize;",
"case type of",
" when '00' datasize = 32;",
" when '01' datasize = 64;",
" when '10' UnallocatedEncoding();",
" when '11'",
" if HaveFP16Ext() then",
" datasize = 16;",
" else",
" UnallocatedEncoding();",
"",
"boolean opa_neg = (o1 == '1');",
"boolean op1_neg = (o0 != o1);"
]
}
],
"name": "FMSUB",
"description": [
"Floating-point Fused Multiply-Subtract (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand1 = V[n];",
"bits(idxdsize) operand2 = V[m];",
"bits(datasize) result;",
"bits(esize) element1;",
"bits(esize) element2 = Elem[operand2, index, esize];",
"",
"for e = 0 to elements-1",
" element1 = Elem[operand1, e, esize];",
" if mulx_op then",
" Elem[result, e, esize] = FPMulX(element1, element2, FPCR);",
" else",
" Elem[result, e, esize] = FPMul(element1, element2, FPCR);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 1 size#2 L#1 M#1 Rm#4 opcode#4 H#1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMUL <Hd>, <Hn>, <Vm>.H[<index>]"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer idxdsize = if H == '1' then 128 else 64;",
"integer index;",
"index = UInt(H:L:M);",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"",
"integer esize = 16;",
"integer datasize = esize;",
"integer elements = 1;",
"boolean mulx_op = (U == '1');"
]
},
{
"pattern": "0 1 U#1 1 1 1 1 1 1 sz#1 L#1 M#1 Rm#4 opcode#4 H#1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMUL <V><d>, <V><n>, <Vm>.<Ts>[<index>]"
}
],
"decoder": [
"integer idxdsize = if H == '1' then 128 else 64; ",
"integer index;",
"bit Rmhi = M;",
"case sz:L of",
" when '0x' index = UInt(H:L);",
" when '10' index = UInt(H);",
" when '11' UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rmhi:Rm);",
"",
"integer esize = 32 << UInt(sz);",
"integer datasize = esize;",
"integer elements = 1;",
"boolean mulx_op = (U == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 1 size#2 L#1 M#1 Rm#4 opcode#4 H#1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMUL <Vd>.<T>, <Vn>.<T>, <Vm>.H[<index>]"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer idxdsize = if H == '1' then 128 else 64;",
"integer index;",
"index = UInt(H:L:M);",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"boolean mulx_op = (U == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 1 1 sz#1 L#1 M#1 Rm#4 opcode#4 H#1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMUL <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>]"
}
],
"decoder": [
"integer idxdsize = if H == '1' then 128 else 64; ",
"integer index;",
"bit Rmhi = M;",
"case sz:L of",
" when '0x' index = UInt(H:L);",
" when '10' index = UInt(H);",
" when '11' UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rmhi:Rm);",
"",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"boolean mulx_op = (U == '1');"
]
}
],
"name": "FMUL (by element)",
"description": [
"Floating-point Multiply (by element)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"bits(datasize) result;",
"bits(esize) element1;",
"bits(esize) element2;",
"",
"for e = 0 to elements-1",
" element1 = Elem[operand1, e, esize];",
" element2 = Elem[operand2, e, esize];",
" Elem[result, e, esize] = FPMul(element1, element2, FPCR);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 a#1 1 0 Rm#5 0 0 opcode#3 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMUL <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 0 sz#1 1 Rm#5 opcode#5 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMUL <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;"
]
}
],
"name": "FMUL (vector)",
"description": [
"Floating-point Multiply (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) result;",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"",
"result = FPMul(operand1, operand2, FPCR);",
"",
"if negated then result = FPNeg(result);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "M#1 0 S#1 1 1 1 1 0 type#2 1 Rm#5 op#1 0 0 0 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": "type == 11",
"format": "FMUL <Hd>, <Hn>, <Hm>"
},
{
"condition": "type == 00",
"format": "FMUL <Sd>, <Sn>, <Sm>"
},
{
"condition": "type == 01",
"format": "FMUL <Dd>, <Dn>, <Dm>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"",
"integer datasize;",
"case type of",
" when '00' datasize = 32;",
" when '01' datasize = 64;",
" when '10' UnallocatedEncoding();",
" when '11'",
" if HaveFP16Ext() then",
" datasize = 16;",
" else",
" UnallocatedEncoding();",
"",
"boolean negated = (op == '1');"
]
}
],
"name": "FMUL (scalar)",
"description": [
"Floating-point Multiply (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand1 = V[n];",
"bits(idxdsize) operand2 = V[m];",
"bits(datasize) result;",
"bits(esize) element1;",
"bits(esize) element2 = Elem[operand2, index, esize];",
"",
"for e = 0 to elements-1",
" element1 = Elem[operand1, e, esize];",
" if mulx_op then",
" Elem[result, e, esize] = FPMulX(element1, element2, FPCR);",
" else",
" Elem[result, e, esize] = FPMul(element1, element2, FPCR);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 1 size#2 L#1 M#1 Rm#4 opcode#4 H#1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMULX <Hd>, <Hn>, <Vm>.H[<index>]"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer idxdsize = if H == '1' then 128 else 64;",
"integer index;",
"index = UInt(H:L:M);",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"",
"integer esize = 16;",
"integer datasize = esize;",
"integer elements = 1;",
"boolean mulx_op = (U == '1');"
]
},
{
"pattern": "0 1 U#1 1 1 1 1 1 1 sz#1 L#1 M#1 Rm#4 opcode#4 H#1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMULX <V><d>, <V><n>, <Vm>.<Ts>[<index>]"
}
],
"decoder": [
"integer idxdsize = if H == '1' then 128 else 64; ",
"integer index;",
"bit Rmhi = M;",
"case sz:L of",
" when '0x' index = UInt(H:L);",
" when '10' index = UInt(H);",
" when '11' UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rmhi:Rm);",
"",
"integer esize = 32 << UInt(sz);",
"integer datasize = esize;",
"integer elements = 1;",
"boolean mulx_op = (U == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 1 size#2 L#1 M#1 Rm#4 opcode#4 H#1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMULX <Vd>.<T>, <Vn>.<T>, <Vm>.H[<index>]"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer idxdsize = if H == '1' then 128 else 64;",
"integer index;",
"index = UInt(H:L:M);",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"boolean mulx_op = (U == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 1 1 sz#1 L#1 M#1 Rm#4 opcode#4 H#1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMULX <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>]"
}
],
"decoder": [
"integer idxdsize = if H == '1' then 128 else 64; ",
"integer index;",
"bit Rmhi = M;",
"case sz:L of",
" when '0x' index = UInt(H:L);",
" when '10' index = UInt(H);",
" when '11' UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rmhi:Rm);",
"",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"boolean mulx_op = (U == '1');"
]
}
],
"name": "FMULX (by element)",
"description": [
"Floating-point Multiply extended (by element)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"bits(datasize) result;",
"bits(esize) element1;",
"bits(esize) element2;",
"",
"for e = 0 to elements-1",
" element1 = Elem[operand1, e, esize];",
" element2 = Elem[operand2, e, esize];",
" Elem[result, e, esize] = FPMulX(element1, element2, FPCR);",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 0 a#1 1 0 Rm#5 0 0 opcode#3 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMULX <Hd>, <Hn>, <Hm>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 16;",
"integer datasize = esize;",
"integer elements = 1;"
]
},
{
"pattern": "0 1 U#1 1 1 1 1 0 0 sz#1 1 Rm#5 opcode#5 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMULX <V><d>, <V><n>, <V><m>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 32 << UInt(sz);",
"integer datasize = esize;",
"integer elements = 1;"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 a#1 1 0 Rm#5 0 0 opcode#3 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMULX <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 0 sz#1 1 Rm#5 opcode#5 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FMULX <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;"
]
}
],
"name": "FMULX",
"description": [
"Floating-point Multiply extended"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"bits(datasize) result;",
"bits(esize) element;",
"",
"for e = 0 to elements-1",
" element = Elem[operand, e, esize];",
" if neg then",
" element = FPNeg(element);",
" else",
" element = FPAbs(element);",
" Elem[result, e, esize] = element;",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 a#1 1 1 1 1 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FNEG <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"boolean neg = (U == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 1 sz#1 1 0 0 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FNEG <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"boolean neg = (U == '1');"
]
}
],
"name": "FNEG (vector)",
"description": [
"Floating-point Negate (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"",
"bits(datasize) result;",
"bits(datasize) operand = V[n];",
"",
"case fpop of",
" when FPUnaryOp_MOV result = operand;",
" when FPUnaryOp_ABS result = FPAbs(operand);",
" when FPUnaryOp_NEG result = FPNeg(operand);",
" when FPUnaryOp_SQRT result = FPSqrt(operand, FPCR);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "M#1 0 S#1 1 1 1 1 0 type#2 1 0 0 0 0 opc#2 1 0 0 0 0 Rn#5 Rd#5",
"formats": [
{
"condition": "type == 11",
"format": "FNEG <Hd>, <Hn>"
},
{
"condition": "type == 00",
"format": "FNEG <Sd>, <Sn>"
},
{
"condition": "type == 01",
"format": "FNEG <Dd>, <Dn>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer datasize;",
"case type of",
" when '00' datasize = 32;",
" when '01' datasize = 64;",
" when '10' UnallocatedEncoding();",
" when '11'",
" if HaveFP16Ext() then",
" datasize = 16;",
" else",
" UnallocatedEncoding();",
"",
"FPUnaryOp fpop;",
"case opc of",
" when '00' fpop = FPUnaryOp_MOV;",
" when '01' fpop = FPUnaryOp_ABS;",
" when '10' fpop = FPUnaryOp_NEG;",
" when '11' fpop = FPUnaryOp_SQRT;"
]
}
],
"name": "FNEG (scalar)",
"description": [
"Floating-point Negate (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) result;",
"bits(datasize) operanda = V[a];",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"",
"if opa_neg then operanda = FPNeg(operanda);",
"if op1_neg then operand1 = FPNeg(operand1);",
"result = FPMulAdd(operanda, operand1, operand2, FPCR);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "M#1 0 S#1 1 1 1 1 1 type#2 o1#1 Rm#5 o0#1 Ra#5 Rn#5 Rd#5",
"formats": [
{
"condition": "type == 11",
"format": "FNMADD <Hd>, <Hn>, <Hm>, <Ha>"
},
{
"condition": "type == 00",
"format": "FNMADD <Sd>, <Sn>, <Sm>, <Sa>"
},
{
"condition": "type == 01",
"format": "FNMADD <Dd>, <Dn>, <Dm>, <Da>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer a = UInt(Ra);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"",
"integer datasize;",
"case type of",
" when '00' datasize = 32;",
" when '01' datasize = 64;",
" when '10' UnallocatedEncoding();",
" when '11'",
" if HaveFP16Ext() then",
" datasize = 16;",
" else",
" UnallocatedEncoding();",
"",
"boolean opa_neg = (o1 == '1');",
"boolean op1_neg = (o0 != o1);"
]
}
],
"name": "FNMADD",
"description": [
"Floating-point Negated fused Multiply-Add (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) result;",
"bits(datasize) operanda = V[a];",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"",
"if opa_neg then operanda = FPNeg(operanda);",
"if op1_neg then operand1 = FPNeg(operand1);",
"result = FPMulAdd(operanda, operand1, operand2, FPCR);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "M#1 0 S#1 1 1 1 1 1 type#2 o1#1 Rm#5 o0#1 Ra#5 Rn#5 Rd#5",
"formats": [
{
"condition": "type == 11",
"format": "FNMSUB <Hd>, <Hn>, <Hm>, <Ha>"
},
{
"condition": "type == 00",
"format": "FNMSUB <Sd>, <Sn>, <Sm>, <Sa>"
},
{
"condition": "type == 01",
"format": "FNMSUB <Dd>, <Dn>, <Dm>, <Da>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer a = UInt(Ra);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"",
"integer datasize;",
"case type of",
" when '00' datasize = 32;",
" when '01' datasize = 64;",
" when '10' UnallocatedEncoding();",
" when '11'",
" if HaveFP16Ext() then",
" datasize = 16;",
" else",
" UnallocatedEncoding();",
"",
"boolean opa_neg = (o1 == '1');",
"boolean op1_neg = (o0 != o1);"
]
}
],
"name": "FNMSUB",
"description": [
"Floating-point Negated fused Multiply-Subtract (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) result;",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"",
"result = FPMul(operand1, operand2, FPCR);",
"",
"if negated then result = FPNeg(result);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "M#1 0 S#1 1 1 1 1 0 type#2 1 Rm#5 op#1 0 0 0 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": "type == 11",
"format": "FNMUL <Hd>, <Hn>, <Hm>"
},
{
"condition": "type == 00",
"format": "FNMUL <Sd>, <Sn>, <Sm>"
},
{
"condition": "type == 01",
"format": "FNMUL <Dd>, <Dn>, <Dm>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"",
"integer datasize;",
"case type of",
" when '00' datasize = 32;",
" when '01' datasize = 64;",
" when '10' UnallocatedEncoding();",
" when '11'",
" if HaveFP16Ext() then",
" datasize = 16;",
" else",
" UnallocatedEncoding();",
"",
"boolean negated = (op == '1');"
]
}
],
"name": "FNMUL (scalar)",
"description": [
"Floating-point Multiply-Negate (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"bits(datasize) result;",
"bits(esize) element;",
"",
"for e = 0 to elements-1",
" element = Elem[operand, e, esize];",
" Elem[result, e, esize] = FPRecipEstimate(element, FPCR);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 0 size<1>#1 1 1 1 1 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FRECPE <Hd>, <Hn>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = esize;",
"integer elements = 1;"
]
},
{
"pattern": "0 1 U#1 1 1 1 1 0 1 sz#1 1 0 0 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FRECPE <V><d>, <V><n>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 32 << UInt(sz);",
"integer datasize = esize;",
"integer elements = 1;"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 a#1 1 1 1 1 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FRECPE <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 1 sz#1 1 0 0 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FRECPE <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;"
]
}
],
"name": "FRECPE",
"description": [
"Floating-point Reciprocal Estimate"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"bits(datasize) result;",
"bits(esize) element1;",
"bits(esize) element2;",
"",
"for e = 0 to elements-1",
" element1 = Elem[operand1, e, esize];",
" element2 = Elem[operand2, e, esize];",
" Elem[result, e, esize] = FPRecipStepFused(element1, element2);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 0 a#1 1 0 Rm#5 0 0 opcode#3 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FRECPS <Hd>, <Hn>, <Hm>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 16;",
"integer datasize = esize;",
"integer elements = 1;"
]
},
{
"pattern": "0 1 U#1 1 1 1 1 0 0 sz#1 1 Rm#5 opcode#5 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FRECPS <V><d>, <V><n>, <V><m>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 32 << UInt(sz);",
"integer datasize = esize;",
"integer elements = 1;"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 a#1 1 0 Rm#5 0 0 opcode#3 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FRECPS <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 0 sz#1 1 Rm#5 opcode#5 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FRECPS <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;"
]
}
],
"name": "FRECPS",
"description": [
"Floating-point Reciprocal Step"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"bits(datasize) result;",
"bits(esize) element;",
"",
"for e = 0 to elements-1",
" element = Elem[operand, e, esize];",
" Elem[result, e, esize] = FPRecpX(element, FPCR);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 0 a#1 1 1 1 1 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FRECPX <Hd>, <Hn>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = esize;",
"integer elements = 1;"
]
},
{
"pattern": "0 1 U#1 1 1 1 1 0 1 sz#1 1 0 0 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FRECPX <V><d>, <V><n>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 32 << UInt(sz);",
"integer datasize = esize;",
"integer elements = 1;"
]
}
],
"name": "FRECPX",
"description": [
"Floating-point Reciprocal exponent (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"bits(datasize) result;",
"bits(esize) element;",
"",
"for e = 0 to elements-1",
" element = Elem[operand, e, esize];",
" Elem[result, e, esize] = FPRoundInt(element, FPCR, rounding, exact);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o2#1 1 1 1 1 0 0 1 1 0 0 o1#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FRINTA <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"boolean exact = FALSE;",
"FPRounding rounding;",
"case U:o1:o2 of",
" when '0xx' rounding = FPDecodeRounding(o1:o2);",
" when '100' rounding = FPRounding_TIEAWAY;",
" when '101' UnallocatedEncoding();",
" when '110' rounding = FPRoundingMode(FPCR); exact = TRUE;",
" when '111' rounding = FPRoundingMode(FPCR);"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o2#1 sz#1 1 0 0 0 0 1 1 0 0 o1#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FRINTA <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"boolean exact = FALSE;",
"FPRounding rounding;",
"case U:o1:o2 of",
" when '0xx' rounding = FPDecodeRounding(o1:o2);",
" when '100' rounding = FPRounding_TIEAWAY;",
" when '101' UnallocatedEncoding();",
" when '110' rounding = FPRoundingMode(FPCR); exact = TRUE;",
" when '111' rounding = FPRoundingMode(FPCR);"
]
}
],
"name": "FRINTA (vector)",
"description": [
"Floating-point Round to Integral, to nearest with ties to Away (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"",
"bits(datasize) result;",
"bits(datasize) operand = V[n];",
"",
"result = FPRoundInt(operand, FPCR, rounding, exact);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "M#1 0 S#1 1 1 1 1 0 type#2 1 0 0 1 rmode#3 1 0 0 0 0 Rn#5 Rd#5",
"formats": [
{
"condition": "type == 11",
"format": "FRINTA <Hd>, <Hn>"
},
{
"condition": "type == 00",
"format": "FRINTA <Sd>, <Sn>"
},
{
"condition": "type == 01",
"format": "FRINTA <Dd>, <Dn>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer datasize;",
"case type of",
" when '00' datasize = 32;",
" when '01' datasize = 64;",
" when '10' UnallocatedEncoding();",
" when '11'",
" if HaveFP16Ext() then",
" datasize = 16;",
" else",
" UnallocatedEncoding();",
"",
"boolean exact = FALSE;",
"FPRounding rounding;",
"case rmode of",
" when '0xx' rounding = FPDecodeRounding(rmode<1:0>);",
" when '100' rounding = FPRounding_TIEAWAY;",
" when '101' UnallocatedEncoding();",
" when '110' rounding = FPRoundingMode(FPCR); exact = TRUE;",
" when '111' rounding = FPRoundingMode(FPCR);"
]
}
],
"name": "FRINTA (scalar)",
"description": [
"Floating-point Round to Integral, to nearest with ties to Away (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"bits(datasize) result;",
"bits(esize) element;",
"",
"for e = 0 to elements-1",
" element = Elem[operand, e, esize];",
" Elem[result, e, esize] = FPRoundInt(element, FPCR, rounding, exact);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o2#1 1 1 1 1 0 0 1 1 0 0 o1#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FRINTI <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"boolean exact = FALSE;",
"FPRounding rounding;",
"case U:o1:o2 of",
" when '0xx' rounding = FPDecodeRounding(o1:o2);",
" when '100' rounding = FPRounding_TIEAWAY;",
" when '101' UnallocatedEncoding();",
" when '110' rounding = FPRoundingMode(FPCR); exact = TRUE;",
" when '111' rounding = FPRoundingMode(FPCR);"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o2#1 sz#1 1 0 0 0 0 1 1 0 0 o1#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FRINTI <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"boolean exact = FALSE;",
"FPRounding rounding;",
"case U:o1:o2 of",
" when '0xx' rounding = FPDecodeRounding(o1:o2);",
" when '100' rounding = FPRounding_TIEAWAY;",
" when '101' UnallocatedEncoding();",
" when '110' rounding = FPRoundingMode(FPCR); exact = TRUE;",
" when '111' rounding = FPRoundingMode(FPCR);"
]
}
],
"name": "FRINTI (vector)",
"description": [
"Floating-point Round to Integral, using current rounding mode (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"",
"bits(datasize) result;",
"bits(datasize) operand = V[n];",
"",
"result = FPRoundInt(operand, FPCR, rounding, exact);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "M#1 0 S#1 1 1 1 1 0 type#2 1 0 0 1 rmode#3 1 0 0 0 0 Rn#5 Rd#5",
"formats": [
{
"condition": "type == 11",
"format": "FRINTI <Hd>, <Hn>"
},
{
"condition": "type == 00",
"format": "FRINTI <Sd>, <Sn>"
},
{
"condition": "type == 01",
"format": "FRINTI <Dd>, <Dn>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer datasize;",
"case type of",
" when '00' datasize = 32;",
" when '01' datasize = 64;",
" when '10' UnallocatedEncoding();",
" when '11'",
" if HaveFP16Ext() then",
" datasize = 16;",
" else",
" UnallocatedEncoding();",
"",
"boolean exact = FALSE;",
"FPRounding rounding;",
"case rmode of",
" when '0xx' rounding = FPDecodeRounding(rmode<1:0>);",
" when '100' rounding = FPRounding_TIEAWAY;",
" when '101' UnallocatedEncoding();",
" when '110' rounding = FPRoundingMode(FPCR); exact = TRUE;",
" when '111' rounding = FPRoundingMode(FPCR);"
]
}
],
"name": "FRINTI (scalar)",
"description": [
"Floating-point Round to Integral, using current rounding mode (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"bits(datasize) result;",
"bits(esize) element;",
"",
"for e = 0 to elements-1",
" element = Elem[operand, e, esize];",
" Elem[result, e, esize] = FPRoundInt(element, FPCR, rounding, exact);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o2#1 1 1 1 1 0 0 1 1 0 0 o1#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FRINTM <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"boolean exact = FALSE;",
"FPRounding rounding;",
"case U:o1:o2 of",
" when '0xx' rounding = FPDecodeRounding(o1:o2);",
" when '100' rounding = FPRounding_TIEAWAY;",
" when '101' UnallocatedEncoding();",
" when '110' rounding = FPRoundingMode(FPCR); exact = TRUE;",
" when '111' rounding = FPRoundingMode(FPCR);"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o2#1 sz#1 1 0 0 0 0 1 1 0 0 o1#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FRINTM <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"boolean exact = FALSE;",
"FPRounding rounding;",
"case U:o1:o2 of",
" when '0xx' rounding = FPDecodeRounding(o1:o2);",
" when '100' rounding = FPRounding_TIEAWAY;",
" when '101' UnallocatedEncoding();",
" when '110' rounding = FPRoundingMode(FPCR); exact = TRUE;",
" when '111' rounding = FPRoundingMode(FPCR);"
]
}
],
"name": "FRINTM (vector)",
"description": [
"Floating-point Round to Integral, toward Minus infinity (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"",
"bits(datasize) result;",
"bits(datasize) operand = V[n];",
"",
"result = FPRoundInt(operand, FPCR, rounding, exact);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "M#1 0 S#1 1 1 1 1 0 type#2 1 0 0 1 rmode#3 1 0 0 0 0 Rn#5 Rd#5",
"formats": [
{
"condition": "type == 11",
"format": "FRINTM <Hd>, <Hn>"
},
{
"condition": "type == 00",
"format": "FRINTM <Sd>, <Sn>"
},
{
"condition": "type == 01",
"format": "FRINTM <Dd>, <Dn>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer datasize;",
"case type of",
" when '00' datasize = 32;",
" when '01' datasize = 64;",
" when '10' UnallocatedEncoding();",
" when '11'",
" if HaveFP16Ext() then",
" datasize = 16;",
" else",
" UnallocatedEncoding();",
"",
"boolean exact = FALSE;",
"FPRounding rounding;",
"case rmode of",
" when '0xx' rounding = FPDecodeRounding(rmode<1:0>);",
" when '100' rounding = FPRounding_TIEAWAY;",
" when '101' UnallocatedEncoding();",
" when '110' rounding = FPRoundingMode(FPCR); exact = TRUE;",
" when '111' rounding = FPRoundingMode(FPCR);"
]
}
],
"name": "FRINTM (scalar)",
"description": [
"Floating-point Round to Integral, toward Minus infinity (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"bits(datasize) result;",
"bits(esize) element;",
"",
"for e = 0 to elements-1",
" element = Elem[operand, e, esize];",
" Elem[result, e, esize] = FPRoundInt(element, FPCR, rounding, exact);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o2#1 1 1 1 1 0 0 1 1 0 0 o1#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FRINTN <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"boolean exact = FALSE;",
"FPRounding rounding;",
"case U:o1:o2 of",
" when '0xx' rounding = FPDecodeRounding(o1:o2);",
" when '100' rounding = FPRounding_TIEAWAY;",
" when '101' UnallocatedEncoding();",
" when '110' rounding = FPRoundingMode(FPCR); exact = TRUE;",
" when '111' rounding = FPRoundingMode(FPCR);"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o2#1 sz#1 1 0 0 0 0 1 1 0 0 o1#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FRINTN <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"boolean exact = FALSE;",
"FPRounding rounding;",
"case U:o1:o2 of",
" when '0xx' rounding = FPDecodeRounding(o1:o2);",
" when '100' rounding = FPRounding_TIEAWAY;",
" when '101' UnallocatedEncoding();",
" when '110' rounding = FPRoundingMode(FPCR); exact = TRUE;",
" when '111' rounding = FPRoundingMode(FPCR);"
]
}
],
"name": "FRINTN (vector)",
"description": [
"Floating-point Round to Integral, to nearest with ties to even (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"",
"bits(datasize) result;",
"bits(datasize) operand = V[n];",
"",
"result = FPRoundInt(operand, FPCR, rounding, exact);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "M#1 0 S#1 1 1 1 1 0 type#2 1 0 0 1 rmode#3 1 0 0 0 0 Rn#5 Rd#5",
"formats": [
{
"condition": "type == 11",
"format": "FRINTN <Hd>, <Hn>"
},
{
"condition": "type == 00",
"format": "FRINTN <Sd>, <Sn>"
},
{
"condition": "type == 01",
"format": "FRINTN <Dd>, <Dn>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer datasize;",
"case type of",
" when '00' datasize = 32;",
" when '01' datasize = 64;",
" when '10' UnallocatedEncoding();",
" when '11'",
" if HaveFP16Ext() then",
" datasize = 16;",
" else",
" UnallocatedEncoding();",
"",
"boolean exact = FALSE;",
"FPRounding rounding;",
"case rmode of",
" when '0xx' rounding = FPDecodeRounding(rmode<1:0>);",
" when '100' rounding = FPRounding_TIEAWAY;",
" when '101' UnallocatedEncoding();",
" when '110' rounding = FPRoundingMode(FPCR); exact = TRUE;",
" when '111' rounding = FPRoundingMode(FPCR);"
]
}
],
"name": "FRINTN (scalar)",
"description": [
"Floating-point Round to Integral, to nearest with ties to even (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"bits(datasize) result;",
"bits(esize) element;",
"",
"for e = 0 to elements-1",
" element = Elem[operand, e, esize];",
" Elem[result, e, esize] = FPRoundInt(element, FPCR, rounding, exact);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o2#1 1 1 1 1 0 0 1 1 0 0 o1#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FRINTP <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"boolean exact = FALSE;",
"FPRounding rounding;",
"case U:o1:o2 of",
" when '0xx' rounding = FPDecodeRounding(o1:o2);",
" when '100' rounding = FPRounding_TIEAWAY;",
" when '101' UnallocatedEncoding();",
" when '110' rounding = FPRoundingMode(FPCR); exact = TRUE;",
" when '111' rounding = FPRoundingMode(FPCR);"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o2#1 sz#1 1 0 0 0 0 1 1 0 0 o1#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FRINTP <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"boolean exact = FALSE;",
"FPRounding rounding;",
"case U:o1:o2 of",
" when '0xx' rounding = FPDecodeRounding(o1:o2);",
" when '100' rounding = FPRounding_TIEAWAY;",
" when '101' UnallocatedEncoding();",
" when '110' rounding = FPRoundingMode(FPCR); exact = TRUE;",
" when '111' rounding = FPRoundingMode(FPCR);"
]
}
],
"name": "FRINTP (vector)",
"description": [
"Floating-point Round to Integral, toward Plus infinity (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"",
"bits(datasize) result;",
"bits(datasize) operand = V[n];",
"",
"result = FPRoundInt(operand, FPCR, rounding, exact);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "M#1 0 S#1 1 1 1 1 0 type#2 1 0 0 1 rmode#3 1 0 0 0 0 Rn#5 Rd#5",
"formats": [
{
"condition": "type == 11",
"format": "FRINTP <Hd>, <Hn>"
},
{
"condition": "type == 00",
"format": "FRINTP <Sd>, <Sn>"
},
{
"condition": "type == 01",
"format": "FRINTP <Dd>, <Dn>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer datasize;",
"case type of",
" when '00' datasize = 32;",
" when '01' datasize = 64;",
" when '10' UnallocatedEncoding();",
" when '11'",
" if HaveFP16Ext() then",
" datasize = 16;",
" else",
" UnallocatedEncoding();",
"",
"boolean exact = FALSE;",
"FPRounding rounding;",
"case rmode of",
" when '0xx' rounding = FPDecodeRounding(rmode<1:0>);",
" when '100' rounding = FPRounding_TIEAWAY;",
" when '101' UnallocatedEncoding();",
" when '110' rounding = FPRoundingMode(FPCR); exact = TRUE;",
" when '111' rounding = FPRoundingMode(FPCR);"
]
}
],
"name": "FRINTP (scalar)",
"description": [
"Floating-point Round to Integral, toward Plus infinity (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"bits(datasize) result;",
"bits(esize) element;",
"",
"for e = 0 to elements-1",
" element = Elem[operand, e, esize];",
" Elem[result, e, esize] = FPRoundInt(element, FPCR, rounding, exact);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o2#1 1 1 1 1 0 0 1 1 0 0 o1#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FRINTX <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"boolean exact = FALSE;",
"FPRounding rounding;",
"case U:o1:o2 of",
" when '0xx' rounding = FPDecodeRounding(o1:o2);",
" when '100' rounding = FPRounding_TIEAWAY;",
" when '101' UnallocatedEncoding();",
" when '110' rounding = FPRoundingMode(FPCR); exact = TRUE;",
" when '111' rounding = FPRoundingMode(FPCR);"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o2#1 sz#1 1 0 0 0 0 1 1 0 0 o1#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FRINTX <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"boolean exact = FALSE;",
"FPRounding rounding;",
"case U:o1:o2 of",
" when '0xx' rounding = FPDecodeRounding(o1:o2);",
" when '100' rounding = FPRounding_TIEAWAY;",
" when '101' UnallocatedEncoding();",
" when '110' rounding = FPRoundingMode(FPCR); exact = TRUE;",
" when '111' rounding = FPRoundingMode(FPCR);"
]
}
],
"name": "FRINTX (vector)",
"description": [
"Floating-point Round to Integral exact, using current rounding mode (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"",
"bits(datasize) result;",
"bits(datasize) operand = V[n];",
"",
"result = FPRoundInt(operand, FPCR, rounding, exact);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "M#1 0 S#1 1 1 1 1 0 type#2 1 0 0 1 rmode#3 1 0 0 0 0 Rn#5 Rd#5",
"formats": [
{
"condition": "type == 11",
"format": "FRINTX <Hd>, <Hn>"
},
{
"condition": "type == 00",
"format": "FRINTX <Sd>, <Sn>"
},
{
"condition": "type == 01",
"format": "FRINTX <Dd>, <Dn>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer datasize;",
"case type of",
" when '00' datasize = 32;",
" when '01' datasize = 64;",
" when '10' UnallocatedEncoding();",
" when '11'",
" if HaveFP16Ext() then",
" datasize = 16;",
" else",
" UnallocatedEncoding();",
"",
"boolean exact = FALSE;",
"FPRounding rounding;",
"case rmode of",
" when '0xx' rounding = FPDecodeRounding(rmode<1:0>);",
" when '100' rounding = FPRounding_TIEAWAY;",
" when '101' UnallocatedEncoding();",
" when '110' rounding = FPRoundingMode(FPCR); exact = TRUE;",
" when '111' rounding = FPRoundingMode(FPCR);"
]
}
],
"name": "FRINTX (scalar)",
"description": [
"Floating-point Round to Integral exact, using current rounding mode (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"bits(datasize) result;",
"bits(esize) element;",
"",
"for e = 0 to elements-1",
" element = Elem[operand, e, esize];",
" Elem[result, e, esize] = FPRoundInt(element, FPCR, rounding, exact);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o2#1 1 1 1 1 0 0 1 1 0 0 o1#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FRINTZ <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"boolean exact = FALSE;",
"FPRounding rounding;",
"case U:o1:o2 of",
" when '0xx' rounding = FPDecodeRounding(o1:o2);",
" when '100' rounding = FPRounding_TIEAWAY;",
" when '101' UnallocatedEncoding();",
" when '110' rounding = FPRoundingMode(FPCR); exact = TRUE;",
" when '111' rounding = FPRoundingMode(FPCR);"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 o2#1 sz#1 1 0 0 0 0 1 1 0 0 o1#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FRINTZ <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"boolean exact = FALSE;",
"FPRounding rounding;",
"case U:o1:o2 of",
" when '0xx' rounding = FPDecodeRounding(o1:o2);",
" when '100' rounding = FPRounding_TIEAWAY;",
" when '101' UnallocatedEncoding();",
" when '110' rounding = FPRoundingMode(FPCR); exact = TRUE;",
" when '111' rounding = FPRoundingMode(FPCR);"
]
}
],
"name": "FRINTZ (vector)",
"description": [
"Floating-point Round to Integral, toward Zero (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"",
"bits(datasize) result;",
"bits(datasize) operand = V[n];",
"",
"result = FPRoundInt(operand, FPCR, rounding, exact);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "M#1 0 S#1 1 1 1 1 0 type#2 1 0 0 1 rmode#3 1 0 0 0 0 Rn#5 Rd#5",
"formats": [
{
"condition": "type == 11",
"format": "FRINTZ <Hd>, <Hn>"
},
{
"condition": "type == 00",
"format": "FRINTZ <Sd>, <Sn>"
},
{
"condition": "type == 01",
"format": "FRINTZ <Dd>, <Dn>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer datasize;",
"case type of",
" when '00' datasize = 32;",
" when '01' datasize = 64;",
" when '10' UnallocatedEncoding();",
" when '11'",
" if HaveFP16Ext() then",
" datasize = 16;",
" else",
" UnallocatedEncoding();",
"",
"boolean exact = FALSE;",
"FPRounding rounding;",
"case rmode of",
" when '0xx' rounding = FPDecodeRounding(rmode<1:0>);",
" when '100' rounding = FPRounding_TIEAWAY;",
" when '101' UnallocatedEncoding();",
" when '110' rounding = FPRoundingMode(FPCR); exact = TRUE;",
" when '111' rounding = FPRoundingMode(FPCR);"
]
}
],
"name": "FRINTZ (scalar)",
"description": [
"Floating-point Round to Integral, toward Zero (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"bits(datasize) result;",
"bits(esize) element;",
"",
"for e = 0 to elements-1",
" element = Elem[operand, e, esize];",
" Elem[result, e, esize] = FPRSqrtEstimate(element, FPCR);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 0 a#1 1 1 1 1 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FRSQRTE <Hd>, <Hn>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = esize;",
"integer elements = 1;"
]
},
{
"pattern": "0 1 U#1 1 1 1 1 0 1 sz#1 1 0 0 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FRSQRTE <V><d>, <V><n>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 32 << UInt(sz);",
"integer datasize = esize;",
"integer elements = 1;"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 a#1 1 1 1 1 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FRSQRTE <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 1 sz#1 1 0 0 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FRSQRTE <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;"
]
}
],
"name": "FRSQRTE",
"description": [
"Floating-point Reciprocal Square Root Estimate"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"bits(datasize) result;",
"bits(esize) element1;",
"bits(esize) element2;",
"",
"for e = 0 to elements-1",
" element1 = Elem[operand1, e, esize];",
" element2 = Elem[operand2, e, esize];",
" Elem[result, e, esize] = FPRSqrtStepFused(element1, element2);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 1 U#1 1 1 1 1 0 a#1 1 0 Rm#5 0 0 opcode#3 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FRSQRTS <Hd>, <Hn>, <Hm>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 16;",
"integer datasize = esize;",
"integer elements = 1;"
]
},
{
"pattern": "0 1 U#1 1 1 1 1 0 1 sz#1 1 Rm#5 opcode#5 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FRSQRTS <V><d>, <V><n>, <V><m>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 32 << UInt(sz);",
"integer datasize = esize;",
"integer elements = 1;"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 a#1 1 0 Rm#5 0 0 opcode#3 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FRSQRTS <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 1 sz#1 1 Rm#5 opcode#5 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FRSQRTS <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;"
]
}
],
"name": "FRSQRTS",
"description": [
"Floating-point Reciprocal Square Root Step"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand = V[n];",
"bits(datasize) result;",
"bits(esize) element;",
"",
"for e = 0 to elements-1",
" element = Elem[operand, e, esize];",
" Elem[result, e, esize] = FPSqrt(element, FPCR);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 a#1 1 1 1 1 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FSQRT <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 1 sz#1 1 0 0 0 0 opcode#5 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FSQRT <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;"
]
}
],
"name": "FSQRT (vector)",
"description": [
"Floating-point Square Root (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"",
"bits(datasize) result;",
"bits(datasize) operand = V[n];",
"",
"case fpop of",
" when FPUnaryOp_MOV result = operand;",
" when FPUnaryOp_ABS result = FPAbs(operand);",
" when FPUnaryOp_NEG result = FPNeg(operand);",
" when FPUnaryOp_SQRT result = FPSqrt(operand, FPCR);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "M#1 0 S#1 1 1 1 1 0 type#2 1 0 0 0 0 opc#2 1 0 0 0 0 Rn#5 Rd#5",
"formats": [
{
"condition": "type == 11",
"format": "FSQRT <Hd>, <Hn>"
},
{
"condition": "type == 00",
"format": "FSQRT <Sd>, <Sn>"
},
{
"condition": "type == 01",
"format": "FSQRT <Dd>, <Dn>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer datasize;",
"case type of",
" when '00' datasize = 32;",
" when '01' datasize = 64;",
" when '10' UnallocatedEncoding();",
" when '11'",
" if HaveFP16Ext() then",
" datasize = 16;",
" else",
" UnallocatedEncoding();",
"",
"FPUnaryOp fpop;",
"case opc of",
" when '00' fpop = FPUnaryOp_MOV;",
" when '01' fpop = FPUnaryOp_ABS;",
" when '10' fpop = FPUnaryOp_NEG;",
" when '11' fpop = FPUnaryOp_SQRT;"
]
}
],
"name": "FSQRT (scalar)",
"description": [
"Floating-point Square Root (scalar)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"bits(datasize) result;",
"bits(esize) element1;",
"bits(esize) element2;",
"bits(esize) diff;",
"",
"for e = 0 to elements-1",
" element1 = Elem[operand1, e, esize];",
" element2 = Elem[operand2, e, esize];",
" diff = FPSub(element1, element2, FPCR);",
" Elem[result, e, esize] = if abs then FPAbs(diff) else diff;",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 a#1 1 0 Rm#5 0 0 opcode#3 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FSUB <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"if !HaveFP16Ext() then UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer esize = 16;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"boolean abs = (U == '1');"
]
},
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 1 sz#1 1 Rm#5 opcode#5 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "FSUB <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"if sz:Q == '10' then ReservedValue();",
"integer esize = 32 << UInt(sz);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"boolean abs = (U == '1');"
]
}
],
"name": "FSUB (vector)",
"description": [
"Floating-point Subtract (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) result;",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"",
"if sub_op then",
" result = FPSub(operand1, operand2, FPCR);",
"else",
" result = FPAdd(operand1, operand2, FPCR);",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "M#1 0 S#1 1 1 1 1 0 type#2 1 Rm#5 0 0 1 op#1 1 0 Rn#5 Rd#5",
"formats": [
{
"condition": "type == 11",
"format": "FSUB <Hd>, <Hn>, <Hm>"
},
{
"condition": "type == 00",
"format": "FSUB <Sd>, <Sn>, <Sm>"
},
{
"condition": "type == 01",
"format": "FSUB <Dd>, <Dn>, <Dm>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"",
"integer datasize;",
"case type of",
" when '00' datasize = 32;",
" when '01' datasize = 64;",
" when '10' UnallocatedEncoding();",
" when '11'",
" if HaveFP16Ext() then",
" datasize = 16;",
" else",
" UnallocatedEncoding();",
"",
"boolean sub_op = (op == '1');"
]
}
],
"name": "FSUB (scalar)",
"description": [
"Floating-point Subtract (scalar)"
]
}
{
"operation": [
"case op of",
" when SystemHintOp_YIELD",
" Hint_Yield();",
"",
" when SystemHintOp_WFE",
" if IsEventRegisterSet() then",
" ClearEventRegister();",
" else",
" if PSTATE.EL == EL0 then",
" // Check for traps described by the OS which may be EL1 or EL2.",
" AArch64.CheckForWFxTrap(EL1, TRUE);",
" if HaveEL(EL2) && !IsSecure() && PSTATE.EL IN {EL0,EL1} && !IsInHost() then",
" // Check for traps described by the Hypervisor.",
" AArch64.CheckForWFxTrap(EL2, TRUE);",
" if HaveEL(EL3) && PSTATE.EL != EL3 then",
" // Check for traps described by the Secure Monitor.",
" AArch64.CheckForWFxTrap(EL3, TRUE);",
" WaitForEvent();",
"",
" when SystemHintOp_WFI",
" if !InterruptPending() then",
" if PSTATE.EL == EL0 then",
" // Check for traps described by the OS which may be EL1 or EL2.",
" AArch64.CheckForWFxTrap(EL1, FALSE);",
" if HaveEL(EL2) && !IsSecure() && PSTATE.EL IN {EL0,EL1} && !IsInHost() then",
" // Check for traps described by the Hypervisor.",
" AArch64.CheckForWFxTrap(EL2, FALSE);",
" if HaveEL(EL3) && PSTATE.EL != EL3 then",
" // Check for traps described by the Secure Monitor.",
" AArch64.CheckForWFxTrap(EL3, FALSE);",
" WaitForInterrupt();",
"",
" when SystemHintOp_SEV",
" SendEvent();",
"",
" when SystemHintOp_SEVL",
" SendEventLocal();",
"",
" when SystemHintOp_ESB",
" ErrorSynchronizationBarrier(MBReqDomain_FullSystem, MBReqTypes_All);",
" AArch64.ESBOperation();",
" if HaveEL(EL2) && !IsSecure() && PSTATE.EL IN {EL0,EL1} then AArch64.vESBOperation();",
" TakeUnmaskedSErrorInterrupts();",
"",
" when SystemHintOp_PSB",
" ProfilingSynchronizationBarrier();",
"",
" otherwise // do nothing"
],
"variants": [
{
"pattern": "1 1 0 1 0 1 0 1 0 0 L#1 op0#2 op1#3 CRn#4 CRm#4 op2#3 Rt#5",
"formats": [
{
"condition": "CRm == 0000 && op2 == 11x",
"format": "HINT #<imm>"
},
{
"condition": "CRm != 00x0",
"format": "HINT #<imm>"
},
{
"condition": "CRm == 0010 && op2 != 00x",
"format": "HINT #<imm>"
}
],
"decoder": [
"SystemHintOp op;",
"",
"case CRm:op2 of",
" when '0000 000' op = SystemHintOp_NOP;",
" when '0000 001' op = SystemHintOp_YIELD;",
" when '0000 010' op = SystemHintOp_WFE;",
" when '0000 011' op = SystemHintOp_WFI;",
" when '0000 100' op = SystemHintOp_SEV;",
" when '0000 101' op = SystemHintOp_SEVL;",
" when '0010 000' ",
" op = if HaveRASExt() then SystemHintOp_ESB else SystemHintOp_NOP;",
" when '0010 001'",
" op = if HaveStatisticalProfiling() then SystemHintOp_PSB else SystemHintOp_NOP;",
" otherwise op = SystemHintOp_NOP;"
]
}
],
"name": "HINT",
"description": [
"Hint instruction"
]
}
{
"operation": [
"Halt(DebugHalt_HaltInstruction);"
],
"variants": [
{
"pattern": "1 1 0 1 0 1 0 0 opc#3 imm16#16 op2#3 LL#2",
"formats": [
{
"condition": null,
"format": "HLT #<imm>"
}
],
"decoder": [
"if EDSCR.HDE == '0' || !HaltingAllowed() then UndefinedFault();"
]
}
],
"name": "HLT",
"description": [
"Halt instruction"
]
}
{
"operation": [
"if !HaveEL(EL2) || PSTATE.EL == EL0 || (PSTATE.EL == EL1 && IsSecure()) then",
" UnallocatedEncoding();",
"",
"hvc_enable = if HaveEL(EL3) then SCR_EL3.HCE else NOT(HCR_EL2.HCD);",
"if hvc_enable == '0' then",
" AArch64.UndefinedFault();",
"else",
" AArch64.CallHypervisor(imm);"
],
"variants": [
{
"pattern": "1 1 0 1 0 1 0 0 opc#3 imm16#16 op2#3 LL#2",
"formats": [
{
"condition": null,
"format": "HVC #<imm>"
}
],
"decoder": [
"bits(16) imm = imm16;"
]
}
],
"name": "HVC",
"description": [
"Hypervisor Call"
]
}
{
"operation": null,
"variants": [
{
"pattern": "1 1 0 1 0 1 0 1 0 0 L#1 op0#2 op1#3 CRn#4 CRm#4 op2#3 Rt#5",
"formats": [
{
"condition": null,
"format": "IC <ic_op>{, <Xt>}"
}
],
"decoder": [
""
]
}
],
"name": "IC",
"description": [
"Instruction Cache operation"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(idxdsize) operand = V[n];",
"bits(128) result;",
"",
"result = V[d];",
"Elem[result, dst_index, esize] = Elem[operand, src_index, esize];",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 Q#1 op#1 0 1 1 1 0 0 0 0 imm5#5 0 imm4#4 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "INS <Vd>.<Ts>[<index1>], <Vn>.<Ts>[<index2>]"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer size = LowestSetBit(imm5);",
"if size > 3 then UnallocatedEncoding();",
"",
"integer dst_index = UInt(imm5<4:size+1>);",
"integer src_index = UInt(imm4<3:size>);",
"integer idxdsize = if imm4<3> == '1' then 128 else 64; ",
"// imm4<size-1:0> is IGNORED ",
"",
"integer esize = 8 << size;"
]
}
],
"name": "INS (element)",
"description": [
"Insert vector element from another vector element"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(esize) element = X[n];",
"bits(datasize) result;",
"",
"result = V[d];",
"Elem[result, index, esize] = element;",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 Q#1 op#1 0 1 1 1 0 0 0 0 imm5#5 0 imm4#4 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "INS <Vd>.<Ts>[<index>], <R><n>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"",
"integer size = LowestSetBit(imm5);",
"",
"if size > 3 then UnallocatedEncoding();",
"integer index = UInt(imm5<4:size+1>);",
"",
"integer esize = 8 << size;",
"integer datasize = 128;"
]
}
],
"name": "INS (general)",
"description": [
"Insert vector element from general-purpose register"
]
}
{
"operation": [
"case op of",
" when MemBarrierOp_DSB",
" DataSynchronizationBarrier(domain, types);",
" when MemBarrierOp_DMB",
" DataMemoryBarrier(domain, types);",
" when MemBarrierOp_ISB",
" InstructionSynchronizationBarrier();"
],
"variants": [
{
"pattern": "1 1 0 1 0 1 0 1 0 0 L#1 op0#2 op1#3 CRn#4 CRm#4 1 opc#2 Rt#5",
"formats": [
{
"condition": null,
"format": "ISB {<option>|#<imm>}"
}
],
"decoder": [
"MemBarrierOp op;",
"MBReqDomain domain;",
"MBReqTypes types;",
"",
"case opc of",
" when '00' op = MemBarrierOp_DSB;",
" when '01' op = MemBarrierOp_DMB;",
" when '10' op = MemBarrierOp_ISB;",
" otherwise UnallocatedEncoding();",
"",
"case CRm<3:2> of",
" when '00' domain = MBReqDomain_OuterShareable;",
" when '01' domain = MBReqDomain_Nonshareable;",
" when '10' domain = MBReqDomain_InnerShareable;",
" when '11' domain = MBReqDomain_FullSystem;",
"",
"case CRm<1:0> of",
" when '01' types = MBReqTypes_Reads;",
" when '10' types = MBReqTypes_Writes;",
" when '11' types = MBReqTypes_All;",
" otherwise",
" types = MBReqTypes_All;",
" domain = MBReqDomain_FullSystem;"
]
}
],
"name": "ISB",
"description": [
"Instruction Synchronization Barrier"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"",
"bits(64) address;",
"bits(64) offs;",
"bits(datasize) rval;",
"integer e, r, s, tt;",
"constant integer ebytes = esize DIV 8;",
"",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"offs = Zeros();",
"for r = 0 to rpt-1",
" for e = 0 to elements-1",
" tt = (t + r) MOD 32;",
" for s = 0 to selem-1",
" rval = V[tt];",
" if memop == MemOp_LOAD then",
" Elem[rval, e, esize] = Mem[address + offs, ebytes, AccType_VEC];",
" V[tt] = rval;",
" else // memop == MemOp_STORE",
" Mem[address + offs, ebytes, AccType_VEC] = Elem[rval, e, esize];",
" offs = offs + ebytes;",
" tt = (tt + 1) MOD 32;",
"",
"if wback then",
" if m != 31 then",
" offs = X[m];",
" if n == 31 then",
" SP[] = address + offs;",
" else",
" X[n] = address + offs;"
],
"variants": [
{
"pattern": "0 Q#1 0 0 1 1 0 0 0 L#1 0 0 0 0 0 0 opcode#4 size#2 Rn#5 Rt#5",
"formats": [
{
"condition": "opcode == 0111",
"format": "LD1 { <Vt>.<T> }, [<Xn|SP>]"
},
{
"condition": "opcode == 1010",
"format": "LD1 { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>]"
},
{
"condition": "opcode == 0110",
"format": "LD1 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>]"
},
{
"condition": "opcode == 0010",
"format": "LD1 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>]"
}
],
"decoder": [
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer m = integer UNKNOWN;",
"boolean wback = FALSE;MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer esize = 8 << UInt(size);",
"integer elements = datasize DIV esize;",
"",
"integer rpt; // number of iterations",
"integer selem; // structure elements",
"",
"case opcode of",
" when '0000' rpt = 1; selem = 4; // LD/ST4 (4 registers)",
" when '0010' rpt = 4; selem = 1; // LD/ST1 (4 registers)",
" when '0100' rpt = 1; selem = 3; // LD/ST3 (3 registers)",
" when '0110' rpt = 3; selem = 1; // LD/ST1 (3 registers)",
" when '0111' rpt = 1; selem = 1; // LD/ST1 (1 register)",
" when '1000' rpt = 1; selem = 2; // LD/ST2 (2 registers)",
" when '1010' rpt = 2; selem = 1; // LD/ST1 (2 registers)",
" otherwise UnallocatedEncoding();",
"",
"// .1D format only permitted with LD1 & ST1",
"if size:Q == '110' && selem != 1 then ReservedValue();"
]
},
{
"pattern": "0 Q#1 0 0 1 1 0 0 1 L#1 0 Rm#5 opcode#4 size#2 Rn#5 Rt#5",
"formats": [
{
"condition": "Rm == 11111 && opcode == 0111",
"format": "LD1 { <Vt>.<T> }, [<Xn|SP>], <imm>"
},
{
"condition": "Rm != 11111 && opcode == 0111",
"format": "LD1 { <Vt>.<T> }, [<Xn|SP>], <Xm>"
},
{
"condition": "Rm == 11111 && opcode == 1010",
"format": "LD1 { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <imm>"
},
{
"condition": "Rm != 11111 && opcode == 1010",
"format": "LD1 { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <Xm>"
},
{
"condition": "Rm == 11111 && opcode == 0110",
"format": "LD1 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <imm>"
},
{
"condition": "Rm != 11111 && opcode == 0110",
"format": "LD1 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <Xm>"
},
{
"condition": "Rm == 11111 && opcode == 0010",
"format": "LD1 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <imm>"
},
{
"condition": "Rm != 11111 && opcode == 0010",
"format": "LD1 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <Xm>"
}
],
"decoder": [
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"boolean wback = TRUE;MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer esize = 8 << UInt(size);",
"integer elements = datasize DIV esize;",
"",
"integer rpt; // number of iterations",
"integer selem; // structure elements",
"",
"case opcode of",
" when '0000' rpt = 1; selem = 4; // LD/ST4 (4 registers)",
" when '0010' rpt = 4; selem = 1; // LD/ST1 (4 registers)",
" when '0100' rpt = 1; selem = 3; // LD/ST3 (3 registers)",
" when '0110' rpt = 3; selem = 1; // LD/ST1 (3 registers)",
" when '0111' rpt = 1; selem = 1; // LD/ST1 (1 register)",
" when '1000' rpt = 1; selem = 2; // LD/ST2 (2 registers)",
" when '1010' rpt = 2; selem = 1; // LD/ST1 (2 registers)",
" otherwise UnallocatedEncoding();",
"",
"// .1D format only permitted with LD1 & ST1",
"if size:Q == '110' && selem != 1 then ReservedValue();"
]
}
],
"name": "LD1 (multiple structures)",
"description": [
"Load multiple single-element structures to one, two, three, or four registers"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"",
"bits(64) address;",
"bits(64) offs;",
"bits(128) rval;",
"bits(esize) element;",
"integer s;",
"constant integer ebytes = esize DIV 8;",
"",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"offs = Zeros();",
"if replicate then",
" // load and replicate to all elements",
" for s = 0 to selem-1",
" element = Mem[address + offs, ebytes, AccType_VEC];",
" // replicate to fill 128- or 64-bit register",
" V[t] = Replicate(element, datasize DIV esize);",
" offs = offs + ebytes;",
" t = (t + 1) MOD 32;",
"else",
" // load/store one element per register",
" for s = 0 to selem-1",
" rval = V[t];",
" if memop == MemOp_LOAD then",
" // insert into one lane of 128-bit register",
" Elem[rval, index, esize] = Mem[address + offs, ebytes, AccType_VEC];",
" V[t] = rval;",
" else // memop == MemOp_STORE",
" // extract from one lane of 128-bit register",
" Mem[address + offs, ebytes, AccType_VEC] = Elem[rval, index, esize];",
" offs = offs + ebytes;",
" t = (t + 1) MOD 32;",
"",
"if wback then",
" if m != 31 then",
" offs = X[m];",
" if n == 31 then",
" SP[] = address + offs;",
" else",
" X[n] = address + offs;"
],
"variants": [
{
"pattern": "0 Q#1 0 0 1 1 0 1 0 L#1 R#1 0 0 0 0 0 opcode#3 S#1 size#2 Rn#5 Rt#5",
"formats": [
{
"condition": "opcode == 000",
"format": "LD1 { <Vt>.B }[<index>], [<Xn|SP>]"
},
{
"condition": "opcode == 010 && size == x0",
"format": "LD1 { <Vt>.H }[<index>], [<Xn|SP>]"
},
{
"condition": "opcode == 100 && size == 00",
"format": "LD1 { <Vt>.S }[<index>], [<Xn|SP>]"
},
{
"condition": "opcode == 100 && S == 0 && size == 01",
"format": "LD1 { <Vt>.D }[<index>], [<Xn|SP>]"
}
],
"decoder": [
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer m = integer UNKNOWN;",
"boolean wback = FALSE;integer scale = UInt(opcode<2:1>);",
"integer selem = UInt(opcode<0>:R) + 1;",
"boolean replicate = FALSE;",
"integer index;",
"",
"case scale of",
" when 3",
" // load and replicate",
" if L == '0' || S == '1' then UnallocatedEncoding();",
" scale = UInt(size);",
" replicate = TRUE;",
" when 0",
" index = UInt(Q:S:size); // B[0-15]",
" when 1",
" if size<0> == '1' then UnallocatedEncoding();",
" index = UInt(Q:S:size<1>); // H[0-7]",
" when 2",
" if size<1> == '1' then UnallocatedEncoding();",
" if size<0> == '0' then",
" index = UInt(Q:S); // S[0-3]",
" else",
" if S == '1' then UnallocatedEncoding();",
" index = UInt(Q); // D[0-1]",
" scale = 3;",
"",
"MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer esize = 8 << scale;"
]
},
{
"pattern": "0 Q#1 0 0 1 1 0 1 1 L#1 R#1 Rm#5 opcode#3 S#1 size#2 Rn#5 Rt#5",
"formats": [
{
"condition": "Rm == 11111 && opcode == 000",
"format": "LD1 { <Vt>.B }[<index>], [<Xn|SP>], #1"
},
{
"condition": "Rm != 11111 && opcode == 000",
"format": "LD1 { <Vt>.B }[<index>], [<Xn|SP>], <Xm>"
},
{
"condition": "Rm == 11111 && opcode == 010 && size == x0",
"format": "LD1 { <Vt>.H }[<index>], [<Xn|SP>], #2"
},
{
"condition": "Rm != 11111 && opcode == 010 && size == x0",
"format": "LD1 { <Vt>.H }[<index>], [<Xn|SP>], <Xm>"
},
{
"condition": "Rm == 11111 && opcode == 100 && size == 00",
"format": "LD1 { <Vt>.S }[<index>], [<Xn|SP>], #4"
},
{
"condition": "Rm != 11111 && opcode == 100 && size == 00",
"format": "LD1 { <Vt>.S }[<index>], [<Xn|SP>], <Xm>"
},
{
"condition": "Rm == 11111 && opcode == 100 && S == 0 && size == 01",
"format": "LD1 { <Vt>.D }[<index>], [<Xn|SP>], #8"
},
{
"condition": "Rm != 11111 && opcode == 100 && S == 0 && size == 01",
"format": "LD1 { <Vt>.D }[<index>], [<Xn|SP>], <Xm>"
}
],
"decoder": [
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"boolean wback = TRUE;integer scale = UInt(opcode<2:1>);",
"integer selem = UInt(opcode<0>:R) + 1;",
"boolean replicate = FALSE;",
"integer index;",
"",
"case scale of",
" when 3",
" // load and replicate",
" if L == '0' || S == '1' then UnallocatedEncoding();",
" scale = UInt(size);",
" replicate = TRUE;",
" when 0",
" index = UInt(Q:S:size); // B[0-15]",
" when 1",
" if size<0> == '1' then UnallocatedEncoding();",
" index = UInt(Q:S:size<1>); // H[0-7]",
" when 2",
" if size<1> == '1' then UnallocatedEncoding();",
" if size<0> == '0' then",
" index = UInt(Q:S); // S[0-3]",
" else",
" if S == '1' then UnallocatedEncoding();",
" index = UInt(Q); // D[0-1]",
" scale = 3;",
"",
"MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer esize = 8 << scale;"
]
}
],
"name": "LD1 (single structure)",
"description": [
"Load one single-element structure to one lane of one register"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"",
"bits(64) address;",
"bits(64) offs;",
"bits(128) rval;",
"bits(esize) element;",
"integer s;",
"constant integer ebytes = esize DIV 8;",
"",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"offs = Zeros();",
"if replicate then",
" // load and replicate to all elements",
" for s = 0 to selem-1",
" element = Mem[address + offs, ebytes, AccType_VEC];",
" // replicate to fill 128- or 64-bit register",
" V[t] = Replicate(element, datasize DIV esize);",
" offs = offs + ebytes;",
" t = (t + 1) MOD 32;",
"else",
" // load/store one element per register",
" for s = 0 to selem-1",
" rval = V[t];",
" if memop == MemOp_LOAD then",
" // insert into one lane of 128-bit register",
" Elem[rval, index, esize] = Mem[address + offs, ebytes, AccType_VEC];",
" V[t] = rval;",
" else // memop == MemOp_STORE",
" // extract from one lane of 128-bit register",
" Mem[address + offs, ebytes, AccType_VEC] = Elem[rval, index, esize];",
" offs = offs + ebytes;",
" t = (t + 1) MOD 32;",
"",
"if wback then",
" if m != 31 then",
" offs = X[m];",
" if n == 31 then",
" SP[] = address + offs;",
" else",
" X[n] = address + offs;"
],
"variants": [
{
"pattern": "0 Q#1 0 0 1 1 0 1 0 L#1 R#1 0 0 0 0 0 opcode#3 S#1 size#2 Rn#5 Rt#5",
"formats": [
{
"condition": null,
"format": "LD1R { <Vt>.<T> }, [<Xn|SP>]"
}
],
"decoder": [
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer m = integer UNKNOWN;",
"boolean wback = FALSE;integer scale = UInt(opcode<2:1>);",
"integer selem = UInt(opcode<0>:R) + 1;",
"boolean replicate = FALSE;",
"integer index;",
"",
"case scale of",
" when 3",
" // load and replicate",
" if L == '0' || S == '1' then UnallocatedEncoding();",
" scale = UInt(size);",
" replicate = TRUE;",
" when 0",
" index = UInt(Q:S:size); // B[0-15]",
" when 1",
" if size<0> == '1' then UnallocatedEncoding();",
" index = UInt(Q:S:size<1>); // H[0-7]",
" when 2",
" if size<1> == '1' then UnallocatedEncoding();",
" if size<0> == '0' then",
" index = UInt(Q:S); // S[0-3]",
" else",
" if S == '1' then UnallocatedEncoding();",
" index = UInt(Q); // D[0-1]",
" scale = 3;",
"",
"MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer esize = 8 << scale;"
]
},
{
"pattern": "0 Q#1 0 0 1 1 0 1 1 L#1 R#1 Rm#5 opcode#3 S#1 size#2 Rn#5 Rt#5",
"formats": [
{
"condition": "Rm == 11111",
"format": "LD1R { <Vt>.<T> }, [<Xn|SP>], <imm>"
},
{
"condition": "Rm != 11111",
"format": "LD1R { <Vt>.<T> }, [<Xn|SP>], <Xm>"
}
],
"decoder": [
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"boolean wback = TRUE;integer scale = UInt(opcode<2:1>);",
"integer selem = UInt(opcode<0>:R) + 1;",
"boolean replicate = FALSE;",
"integer index;",
"",
"case scale of",
" when 3",
" // load and replicate",
" if L == '0' || S == '1' then UnallocatedEncoding();",
" scale = UInt(size);",
" replicate = TRUE;",
" when 0",
" index = UInt(Q:S:size); // B[0-15]",
" when 1",
" if size<0> == '1' then UnallocatedEncoding();",
" index = UInt(Q:S:size<1>); // H[0-7]",
" when 2",
" if size<1> == '1' then UnallocatedEncoding();",
" if size<0> == '0' then",
" index = UInt(Q:S); // S[0-3]",
" else",
" if S == '1' then UnallocatedEncoding();",
" index = UInt(Q); // D[0-1]",
" scale = 3;",
"",
"MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer esize = 8 << scale;"
]
}
],
"name": "LD1R",
"description": [
"Load one single-element structure and Replicate to all lanes (of one register)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"",
"bits(64) address;",
"bits(64) offs;",
"bits(datasize) rval;",
"integer e, r, s, tt;",
"constant integer ebytes = esize DIV 8;",
"",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"offs = Zeros();",
"for r = 0 to rpt-1",
" for e = 0 to elements-1",
" tt = (t + r) MOD 32;",
" for s = 0 to selem-1",
" rval = V[tt];",
" if memop == MemOp_LOAD then",
" Elem[rval, e, esize] = Mem[address + offs, ebytes, AccType_VEC];",
" V[tt] = rval;",
" else // memop == MemOp_STORE",
" Mem[address + offs, ebytes, AccType_VEC] = Elem[rval, e, esize];",
" offs = offs + ebytes;",
" tt = (tt + 1) MOD 32;",
"",
"if wback then",
" if m != 31 then",
" offs = X[m];",
" if n == 31 then",
" SP[] = address + offs;",
" else",
" X[n] = address + offs;"
],
"variants": [
{
"pattern": "0 Q#1 0 0 1 1 0 0 0 L#1 0 0 0 0 0 0 opcode#4 size#2 Rn#5 Rt#5",
"formats": [
{
"condition": null,
"format": "LD2 { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>]"
}
],
"decoder": [
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer m = integer UNKNOWN;",
"boolean wback = FALSE;MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer esize = 8 << UInt(size);",
"integer elements = datasize DIV esize;",
"",
"integer rpt; // number of iterations",
"integer selem; // structure elements ",
"",
"case opcode of",
" when '0000' rpt = 1; selem = 4; // LD/ST4 (4 registers)",
" when '0010' rpt = 4; selem = 1; // LD/ST1 (4 registers)",
" when '0100' rpt = 1; selem = 3; // LD/ST3 (3 registers)",
" when '0110' rpt = 3; selem = 1; // LD/ST1 (3 registers)",
" when '0111' rpt = 1; selem = 1; // LD/ST1 (1 register)",
" when '1000' rpt = 1; selem = 2; // LD/ST2 (2 registers)",
" when '1010' rpt = 2; selem = 1; // LD/ST1 (2 registers)",
" otherwise UnallocatedEncoding();",
"",
"// .1D format only permitted with LD1 & ST1",
"if size:Q == '110' && selem != 1 then ReservedValue();"
]
},
{
"pattern": "0 Q#1 0 0 1 1 0 0 1 L#1 0 Rm#5 opcode#4 size#2 Rn#5 Rt#5",
"formats": [
{
"condition": "Rm == 11111",
"format": "LD2 { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <imm>"
},
{
"condition": "Rm != 11111",
"format": "LD2 { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <Xm>"
}
],
"decoder": [
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"boolean wback = TRUE;MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer esize = 8 << UInt(size);",
"integer elements = datasize DIV esize;",
"",
"integer rpt; // number of iterations",
"integer selem; // structure elements ",
"",
"case opcode of",
" when '0000' rpt = 1; selem = 4; // LD/ST4 (4 registers)",
" when '0010' rpt = 4; selem = 1; // LD/ST1 (4 registers)",
" when '0100' rpt = 1; selem = 3; // LD/ST3 (3 registers)",
" when '0110' rpt = 3; selem = 1; // LD/ST1 (3 registers)",
" when '0111' rpt = 1; selem = 1; // LD/ST1 (1 register)",
" when '1000' rpt = 1; selem = 2; // LD/ST2 (2 registers)",
" when '1010' rpt = 2; selem = 1; // LD/ST1 (2 registers)",
" otherwise UnallocatedEncoding();",
"",
"// .1D format only permitted with LD1 & ST1",
"if size:Q == '110' && selem != 1 then ReservedValue();"
]
}
],
"name": "LD2 (multiple structures)",
"description": [
"Load multiple 2-element structures to two registers"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"",
"bits(64) address;",
"bits(64) offs;",
"bits(128) rval;",
"bits(esize) element;",
"integer s;",
"constant integer ebytes = esize DIV 8;",
"",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"offs = Zeros();",
"if replicate then",
" // load and replicate to all elements",
" for s = 0 to selem-1",
" element = Mem[address + offs, ebytes, AccType_VEC];",
" // replicate to fill 128- or 64-bit register",
" V[t] = Replicate(element, datasize DIV esize);",
" offs = offs + ebytes;",
" t = (t + 1) MOD 32;",
"else",
" // load/store one element per register",
" for s = 0 to selem-1",
" rval = V[t];",
" if memop == MemOp_LOAD then",
" // insert into one lane of 128-bit register",
" Elem[rval, index, esize] = Mem[address + offs, ebytes, AccType_VEC];",
" V[t] = rval;",
" else // memop == MemOp_STORE",
" // extract from one lane of 128-bit register",
" Mem[address + offs, ebytes, AccType_VEC] = Elem[rval, index, esize];",
" offs = offs + ebytes;",
" t = (t + 1) MOD 32;",
"",
"if wback then",
" if m != 31 then",
" offs = X[m];",
" if n == 31 then",
" SP[] = address + offs;",
" else",
" X[n] = address + offs;"
],
"variants": [
{
"pattern": "0 Q#1 0 0 1 1 0 1 0 L#1 R#1 0 0 0 0 0 opcode#3 S#1 size#2 Rn#5 Rt#5",
"formats": [
{
"condition": "opcode == 000",
"format": "LD2 { <Vt>.B, <Vt2>.B }[<index>], [<Xn|SP>]"
},
{
"condition": "opcode == 010 && size == x0",
"format": "LD2 { <Vt>.H, <Vt2>.H }[<index>], [<Xn|SP>]"
},
{
"condition": "opcode == 100 && size == 00",
"format": "LD2 { <Vt>.S, <Vt2>.S }[<index>], [<Xn|SP>]"
},
{
"condition": "opcode == 100 && S == 0 && size == 01",
"format": "LD2 { <Vt>.D, <Vt2>.D }[<index>], [<Xn|SP>]"
}
],
"decoder": [
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer m = integer UNKNOWN;",
"boolean wback = FALSE;integer scale = UInt(opcode<2:1>);",
"integer selem = UInt(opcode<0>:R) + 1;",
"boolean replicate = FALSE;",
"integer index;",
"",
"case scale of",
" when 3",
" // load and replicate",
" if L == '0' || S == '1' then UnallocatedEncoding();",
" scale = UInt(size);",
" replicate = TRUE;",
" when 0",
" index = UInt(Q:S:size); // B[0-15]",
" when 1",
" if size<0> == '1' then UnallocatedEncoding();",
" index = UInt(Q:S:size<1>); // H[0-7]",
" when 2",
" if size<1> == '1' then UnallocatedEncoding();",
" if size<0> == '0' then",
" index = UInt(Q:S); // S[0-3]",
" else",
" if S == '1' then UnallocatedEncoding();",
" index = UInt(Q); // D[0-1]",
" scale = 3;",
"",
"MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer esize = 8 << scale;"
]
},
{
"pattern": "0 Q#1 0 0 1 1 0 1 1 L#1 R#1 Rm#5 opcode#3 S#1 size#2 Rn#5 Rt#5",
"formats": [
{
"condition": "Rm == 11111 && opcode == 000",
"format": "LD2 { <Vt>.B, <Vt2>.B }[<index>], [<Xn|SP>], #2"
},
{
"condition": "Rm != 11111 && opcode == 000",
"format": "LD2 { <Vt>.B, <Vt2>.B }[<index>], [<Xn|SP>], <Xm>"
},
{
"condition": "Rm == 11111 && opcode == 010 && size == x0",
"format": "LD2 { <Vt>.H, <Vt2>.H }[<index>], [<Xn|SP>], #4"
},
{
"condition": "Rm != 11111 && opcode == 010 && size == x0",
"format": "LD2 { <Vt>.H, <Vt2>.H }[<index>], [<Xn|SP>], <Xm>"
},
{
"condition": "Rm == 11111 && opcode == 100 && size == 00",
"format": "LD2 { <Vt>.S, <Vt2>.S }[<index>], [<Xn|SP>], #8"
},
{
"condition": "Rm != 11111 && opcode == 100 && size == 00",
"format": "LD2 { <Vt>.S, <Vt2>.S }[<index>], [<Xn|SP>], <Xm>"
},
{
"condition": "Rm == 11111 && opcode == 100 && S == 0 && size == 01",
"format": "LD2 { <Vt>.D, <Vt2>.D }[<index>], [<Xn|SP>], #16"
},
{
"condition": "Rm != 11111 && opcode == 100 && S == 0 && size == 01",
"format": "LD2 { <Vt>.D, <Vt2>.D }[<index>], [<Xn|SP>], <Xm>"
}
],
"decoder": [
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"boolean wback = TRUE;integer scale = UInt(opcode<2:1>);",
"integer selem = UInt(opcode<0>:R) + 1;",
"boolean replicate = FALSE;",
"integer index;",
"",
"case scale of",
" when 3",
" // load and replicate",
" if L == '0' || S == '1' then UnallocatedEncoding();",
" scale = UInt(size);",
" replicate = TRUE;",
" when 0",
" index = UInt(Q:S:size); // B[0-15]",
" when 1",
" if size<0> == '1' then UnallocatedEncoding();",
" index = UInt(Q:S:size<1>); // H[0-7]",
" when 2",
" if size<1> == '1' then UnallocatedEncoding();",
" if size<0> == '0' then",
" index = UInt(Q:S); // S[0-3]",
" else",
" if S == '1' then UnallocatedEncoding();",
" index = UInt(Q); // D[0-1]",
" scale = 3;",
"",
"MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer esize = 8 << scale;"
]
}
],
"name": "LD2 (single structure)",
"description": [
"Load single 2-element structure to one lane of two registers"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"",
"bits(64) address;",
"bits(64) offs;",
"bits(128) rval;",
"bits(esize) element;",
"integer s;",
"constant integer ebytes = esize DIV 8;",
"",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"offs = Zeros();",
"if replicate then",
" // load and replicate to all elements",
" for s = 0 to selem-1",
" element = Mem[address + offs, ebytes, AccType_VEC];",
" // replicate to fill 128- or 64-bit register",
" V[t] = Replicate(element, datasize DIV esize);",
" offs = offs + ebytes;",
" t = (t + 1) MOD 32;",
"else",
" // load/store one element per register",
" for s = 0 to selem-1",
" rval = V[t];",
" if memop == MemOp_LOAD then",
" // insert into one lane of 128-bit register",
" Elem[rval, index, esize] = Mem[address + offs, ebytes, AccType_VEC];",
" V[t] = rval;",
" else // memop == MemOp_STORE",
" // extract from one lane of 128-bit register",
" Mem[address + offs, ebytes, AccType_VEC] = Elem[rval, index, esize];",
" offs = offs + ebytes;",
" t = (t + 1) MOD 32;",
"",
"if wback then",
" if m != 31 then",
" offs = X[m];",
" if n == 31 then",
" SP[] = address + offs;",
" else",
" X[n] = address + offs;"
],
"variants": [
{
"pattern": "0 Q#1 0 0 1 1 0 1 0 L#1 R#1 0 0 0 0 0 opcode#3 S#1 size#2 Rn#5 Rt#5",
"formats": [
{
"condition": null,
"format": "LD2R { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>]"
}
],
"decoder": [
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer m = integer UNKNOWN;",
"boolean wback = FALSE;integer scale = UInt(opcode<2:1>);",
"integer selem = UInt(opcode<0>:R) + 1;",
"boolean replicate = FALSE;",
"integer index;",
"",
"case scale of",
" when 3",
" // load and replicate",
" if L == '0' || S == '1' then UnallocatedEncoding();",
" scale = UInt(size);",
" replicate = TRUE;",
" when 0",
" index = UInt(Q:S:size); // B[0-15]",
" when 1",
" if size<0> == '1' then UnallocatedEncoding();",
" index = UInt(Q:S:size<1>); // H[0-7]",
" when 2",
" if size<1> == '1' then UnallocatedEncoding();",
" if size<0> == '0' then",
" index = UInt(Q:S); // S[0-3]",
" else",
" if S == '1' then UnallocatedEncoding();",
" index = UInt(Q); // D[0-1]",
" scale = 3;",
"",
"MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer esize = 8 << scale;"
]
},
{
"pattern": "0 Q#1 0 0 1 1 0 1 1 L#1 R#1 Rm#5 opcode#3 S#1 size#2 Rn#5 Rt#5",
"formats": [
{
"condition": "Rm == 11111",
"format": "LD2R { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <imm>"
},
{
"condition": "Rm != 11111",
"format": "LD2R { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <Xm>"
}
],
"decoder": [
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"boolean wback = TRUE;integer scale = UInt(opcode<2:1>);",
"integer selem = UInt(opcode<0>:R) + 1;",
"boolean replicate = FALSE;",
"integer index;",
"",
"case scale of",
" when 3",
" // load and replicate",
" if L == '0' || S == '1' then UnallocatedEncoding();",
" scale = UInt(size);",
" replicate = TRUE;",
" when 0",
" index = UInt(Q:S:size); // B[0-15]",
" when 1",
" if size<0> == '1' then UnallocatedEncoding();",
" index = UInt(Q:S:size<1>); // H[0-7]",
" when 2",
" if size<1> == '1' then UnallocatedEncoding();",
" if size<0> == '0' then",
" index = UInt(Q:S); // S[0-3]",
" else",
" if S == '1' then UnallocatedEncoding();",
" index = UInt(Q); // D[0-1]",
" scale = 3;",
"",
"MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer esize = 8 << scale;"
]
}
],
"name": "LD2R",
"description": [
"Load single 2-element structure and Replicate to all lanes of two registers"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"",
"bits(64) address;",
"bits(64) offs;",
"bits(datasize) rval;",
"integer e, r, s, tt;",
"constant integer ebytes = esize DIV 8;",
"",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"offs = Zeros();",
"for r = 0 to rpt-1",
" for e = 0 to elements-1",
" tt = (t + r) MOD 32;",
" for s = 0 to selem-1",
" rval = V[tt];",
" if memop == MemOp_LOAD then",
" Elem[rval, e, esize] = Mem[address + offs, ebytes, AccType_VEC];",
" V[tt] = rval;",
" else // memop == MemOp_STORE",
" Mem[address + offs, ebytes, AccType_VEC] = Elem[rval, e, esize];",
" offs = offs + ebytes;",
" tt = (tt + 1) MOD 32;",
"",
"if wback then",
" if m != 31 then",
" offs = X[m];",
" if n == 31 then",
" SP[] = address + offs;",
" else",
" X[n] = address + offs;"
],
"variants": [
{
"pattern": "0 Q#1 0 0 1 1 0 0 0 L#1 0 0 0 0 0 0 opcode#4 size#2 Rn#5 Rt#5",
"formats": [
{
"condition": null,
"format": "LD3 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>]"
}
],
"decoder": [
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer m = integer UNKNOWN;",
"boolean wback = FALSE;MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer esize = 8 << UInt(size);",
"integer elements = datasize DIV esize;",
"",
"integer rpt; // number of iterations",
"integer selem; // structure elements ",
"",
"case opcode of",
" when '0000' rpt = 1; selem = 4; // LD/ST4 (4 registers)",
" when '0010' rpt = 4; selem = 1; // LD/ST1 (4 registers)",
" when '0100' rpt = 1; selem = 3; // LD/ST3 (3 registers)",
" when '0110' rpt = 3; selem = 1; // LD/ST1 (3 registers)",
" when '0111' rpt = 1; selem = 1; // LD/ST1 (1 register)",
" when '1000' rpt = 1; selem = 2; // LD/ST2 (2 registers)",
" when '1010' rpt = 2; selem = 1; // LD/ST1 (2 registers)",
" otherwise UnallocatedEncoding();",
"",
"// .1D format only permitted with LD1 & ST1",
"if size:Q == '110' && selem != 1 then ReservedValue();"
]
},
{
"pattern": "0 Q#1 0 0 1 1 0 0 1 L#1 0 Rm#5 opcode#4 size#2 Rn#5 Rt#5",
"formats": [
{
"condition": "Rm == 11111",
"format": "LD3 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <imm>"
},
{
"condition": "Rm != 11111",
"format": "LD3 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <Xm>"
}
],
"decoder": [
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"boolean wback = TRUE;MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer esize = 8 << UInt(size);",
"integer elements = datasize DIV esize;",
"",
"integer rpt; // number of iterations",
"integer selem; // structure elements ",
"",
"case opcode of",
" when '0000' rpt = 1; selem = 4; // LD/ST4 (4 registers)",
" when '0010' rpt = 4; selem = 1; // LD/ST1 (4 registers)",
" when '0100' rpt = 1; selem = 3; // LD/ST3 (3 registers)",
" when '0110' rpt = 3; selem = 1; // LD/ST1 (3 registers)",
" when '0111' rpt = 1; selem = 1; // LD/ST1 (1 register)",
" when '1000' rpt = 1; selem = 2; // LD/ST2 (2 registers)",
" when '1010' rpt = 2; selem = 1; // LD/ST1 (2 registers)",
" otherwise UnallocatedEncoding();",
"",
"// .1D format only permitted with LD1 & ST1",
"if size:Q == '110' && selem != 1 then ReservedValue();"
]
}
],
"name": "LD3 (multiple structures)",
"description": [
"Load multiple 3-element structures to three registers"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"",
"bits(64) address;",
"bits(64) offs;",
"bits(128) rval;",
"bits(esize) element;",
"integer s;",
"constant integer ebytes = esize DIV 8;",
"",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"offs = Zeros();",
"if replicate then",
" // load and replicate to all elements",
" for s = 0 to selem-1",
" element = Mem[address + offs, ebytes, AccType_VEC];",
" // replicate to fill 128- or 64-bit register",
" V[t] = Replicate(element, datasize DIV esize);",
" offs = offs + ebytes;",
" t = (t + 1) MOD 32;",
"else",
" // load/store one element per register",
" for s = 0 to selem-1",
" rval = V[t];",
" if memop == MemOp_LOAD then",
" // insert into one lane of 128-bit register",
" Elem[rval, index, esize] = Mem[address + offs, ebytes, AccType_VEC];",
" V[t] = rval;",
" else // memop == MemOp_STORE",
" // extract from one lane of 128-bit register",
" Mem[address + offs, ebytes, AccType_VEC] = Elem[rval, index, esize];",
" offs = offs + ebytes;",
" t = (t + 1) MOD 32;",
"",
"if wback then",
" if m != 31 then",
" offs = X[m];",
" if n == 31 then",
" SP[] = address + offs;",
" else",
" X[n] = address + offs;"
],
"variants": [
{
"pattern": "0 Q#1 0 0 1 1 0 1 0 L#1 R#1 0 0 0 0 0 opcode#3 S#1 size#2 Rn#5 Rt#5",
"formats": [
{
"condition": "opcode == 001",
"format": "LD3 { <Vt>.B, <Vt2>.B, <Vt3>.B }[<index>], [<Xn|SP>]"
},
{
"condition": "opcode == 011 && size == x0",
"format": "LD3 { <Vt>.H, <Vt2>.H, <Vt3>.H }[<index>], [<Xn|SP>]"
},
{
"condition": "opcode == 101 && size == 00",
"format": "LD3 { <Vt>.S, <Vt2>.S, <Vt3>.S }[<index>], [<Xn|SP>]"
},
{
"condition": "opcode == 101 && S == 0 && size == 01",
"format": "LD3 { <Vt>.D, <Vt2>.D, <Vt3>.D }[<index>], [<Xn|SP>]"
}
],
"decoder": [
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer m = integer UNKNOWN;",
"boolean wback = FALSE;integer scale = UInt(opcode<2:1>);",
"integer selem = UInt(opcode<0>:R) + 1;",
"boolean replicate = FALSE;",
"integer index;",
"",
"case scale of",
" when 3",
" // load and replicate",
" if L == '0' || S == '1' then UnallocatedEncoding();",
" scale = UInt(size);",
" replicate = TRUE;",
" when 0",
" index = UInt(Q:S:size); // B[0-15]",
" when 1",
" if size<0> == '1' then UnallocatedEncoding();",
" index = UInt(Q:S:size<1>); // H[0-7]",
" when 2",
" if size<1> == '1' then UnallocatedEncoding();",
" if size<0> == '0' then",
" index = UInt(Q:S); // S[0-3]",
" else",
" if S == '1' then UnallocatedEncoding();",
" index = UInt(Q); // D[0-1]",
" scale = 3;",
"",
"MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer esize = 8 << scale;"
]
},
{
"pattern": "0 Q#1 0 0 1 1 0 1 1 L#1 R#1 Rm#5 opcode#3 S#1 size#2 Rn#5 Rt#5",
"formats": [
{
"condition": "Rm == 11111 && opcode == 001",
"format": "LD3 { <Vt>.B, <Vt2>.B, <Vt3>.B }[<index>], [<Xn|SP>], #3"
},
{
"condition": "Rm != 11111 && opcode == 001",
"format": "LD3 { <Vt>.B, <Vt2>.B, <Vt3>.B }[<index>], [<Xn|SP>], <Xm>"
},
{
"condition": "Rm == 11111 && opcode == 011 && size == x0",
"format": "LD3 { <Vt>.H, <Vt2>.H, <Vt3>.H }[<index>], [<Xn|SP>], #6"
},
{
"condition": "Rm != 11111 && opcode == 011 && size == x0",
"format": "LD3 { <Vt>.H, <Vt2>.H, <Vt3>.H }[<index>], [<Xn|SP>], <Xm>"
},
{
"condition": "Rm == 11111 && opcode == 101 && size == 00",
"format": "LD3 { <Vt>.S, <Vt2>.S, <Vt3>.S }[<index>], [<Xn|SP>], #12"
},
{
"condition": "Rm != 11111 && opcode == 101 && size == 00",
"format": "LD3 { <Vt>.S, <Vt2>.S, <Vt3>.S }[<index>], [<Xn|SP>], <Xm>"
},
{
"condition": "Rm == 11111 && opcode == 101 && S == 0 && size == 01",
"format": "LD3 { <Vt>.D, <Vt2>.D, <Vt3>.D }[<index>], [<Xn|SP>], #24"
},
{
"condition": "Rm != 11111 && opcode == 101 && S == 0 && size == 01",
"format": "LD3 { <Vt>.D, <Vt2>.D, <Vt3>.D }[<index>], [<Xn|SP>], <Xm>"
}
],
"decoder": [
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"boolean wback = TRUE;integer scale = UInt(opcode<2:1>);",
"integer selem = UInt(opcode<0>:R) + 1;",
"boolean replicate = FALSE;",
"integer index;",
"",
"case scale of",
" when 3",
" // load and replicate",
" if L == '0' || S == '1' then UnallocatedEncoding();",
" scale = UInt(size);",
" replicate = TRUE;",
" when 0",
" index = UInt(Q:S:size); // B[0-15]",
" when 1",
" if size<0> == '1' then UnallocatedEncoding();",
" index = UInt(Q:S:size<1>); // H[0-7]",
" when 2",
" if size<1> == '1' then UnallocatedEncoding();",
" if size<0> == '0' then",
" index = UInt(Q:S); // S[0-3]",
" else",
" if S == '1' then UnallocatedEncoding();",
" index = UInt(Q); // D[0-1]",
" scale = 3;",
"",
"MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer esize = 8 << scale;"
]
}
],
"name": "LD3 (single structure)",
"description": [
"Load single 3-element structure to one lane of three registers)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"",
"bits(64) address;",
"bits(64) offs;",
"bits(128) rval;",
"bits(esize) element;",
"integer s;",
"constant integer ebytes = esize DIV 8;",
"",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"offs = Zeros();",
"if replicate then",
" // load and replicate to all elements",
" for s = 0 to selem-1",
" element = Mem[address + offs, ebytes, AccType_VEC];",
" // replicate to fill 128- or 64-bit register",
" V[t] = Replicate(element, datasize DIV esize);",
" offs = offs + ebytes;",
" t = (t + 1) MOD 32;",
"else",
" // load/store one element per register",
" for s = 0 to selem-1",
" rval = V[t];",
" if memop == MemOp_LOAD then",
" // insert into one lane of 128-bit register",
" Elem[rval, index, esize] = Mem[address + offs, ebytes, AccType_VEC];",
" V[t] = rval;",
" else // memop == MemOp_STORE",
" // extract from one lane of 128-bit register",
" Mem[address + offs, ebytes, AccType_VEC] = Elem[rval, index, esize];",
" offs = offs + ebytes;",
" t = (t + 1) MOD 32;",
"",
"if wback then",
" if m != 31 then",
" offs = X[m];",
" if n == 31 then",
" SP[] = address + offs;",
" else",
" X[n] = address + offs;"
],
"variants": [
{
"pattern": "0 Q#1 0 0 1 1 0 1 0 L#1 R#1 0 0 0 0 0 opcode#3 S#1 size#2 Rn#5 Rt#5",
"formats": [
{
"condition": null,
"format": "LD3R { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>]"
}
],
"decoder": [
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer m = integer UNKNOWN;",
"boolean wback = FALSE;integer scale = UInt(opcode<2:1>);",
"integer selem = UInt(opcode<0>:R) + 1;",
"boolean replicate = FALSE;",
"integer index;",
"",
"case scale of",
" when 3",
" // load and replicate",
" if L == '0' || S == '1' then UnallocatedEncoding();",
" scale = UInt(size);",
" replicate = TRUE;",
" when 0",
" index = UInt(Q:S:size); // B[0-15]",
" when 1",
" if size<0> == '1' then UnallocatedEncoding();",
" index = UInt(Q:S:size<1>); // H[0-7]",
" when 2",
" if size<1> == '1' then UnallocatedEncoding();",
" if size<0> == '0' then",
" index = UInt(Q:S); // S[0-3]",
" else",
" if S == '1' then UnallocatedEncoding();",
" index = UInt(Q); // D[0-1]",
" scale = 3;",
"",
"MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer esize = 8 << scale;"
]
},
{
"pattern": "0 Q#1 0 0 1 1 0 1 1 L#1 R#1 Rm#5 opcode#3 S#1 size#2 Rn#5 Rt#5",
"formats": [
{
"condition": "Rm == 11111",
"format": "LD3R { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <imm>"
},
{
"condition": "Rm != 11111",
"format": "LD3R { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <Xm>"
}
],
"decoder": [
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"boolean wback = TRUE;integer scale = UInt(opcode<2:1>);",
"integer selem = UInt(opcode<0>:R) + 1;",
"boolean replicate = FALSE;",
"integer index;",
"",
"case scale of",
" when 3",
" // load and replicate",
" if L == '0' || S == '1' then UnallocatedEncoding();",
" scale = UInt(size);",
" replicate = TRUE;",
" when 0",
" index = UInt(Q:S:size); // B[0-15]",
" when 1",
" if size<0> == '1' then UnallocatedEncoding();",
" index = UInt(Q:S:size<1>); // H[0-7]",
" when 2",
" if size<1> == '1' then UnallocatedEncoding();",
" if size<0> == '0' then",
" index = UInt(Q:S); // S[0-3]",
" else",
" if S == '1' then UnallocatedEncoding();",
" index = UInt(Q); // D[0-1]",
" scale = 3;",
"",
"MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer esize = 8 << scale;"
]
}
],
"name": "LD3R",
"description": [
"Load single 3-element structure and Replicate to all lanes of three registers"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"",
"bits(64) address;",
"bits(64) offs;",
"bits(datasize) rval;",
"integer e, r, s, tt;",
"constant integer ebytes = esize DIV 8;",
"",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"offs = Zeros();",
"for r = 0 to rpt-1",
" for e = 0 to elements-1",
" tt = (t + r) MOD 32;",
" for s = 0 to selem-1",
" rval = V[tt];",
" if memop == MemOp_LOAD then",
" Elem[rval, e, esize] = Mem[address + offs, ebytes, AccType_VEC];",
" V[tt] = rval;",
" else // memop == MemOp_STORE",
" Mem[address + offs, ebytes, AccType_VEC] = Elem[rval, e, esize];",
" offs = offs + ebytes;",
" tt = (tt + 1) MOD 32;",
"",
"if wback then",
" if m != 31 then",
" offs = X[m];",
" if n == 31 then",
" SP[] = address + offs;",
" else",
" X[n] = address + offs;"
],
"variants": [
{
"pattern": "0 Q#1 0 0 1 1 0 0 0 L#1 0 0 0 0 0 0 opcode#4 size#2 Rn#5 Rt#5",
"formats": [
{
"condition": null,
"format": "LD4 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>]"
}
],
"decoder": [
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer m = integer UNKNOWN;",
"boolean wback = FALSE;MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer esize = 8 << UInt(size);",
"integer elements = datasize DIV esize;",
"",
"integer rpt; // number of iterations",
"integer selem; // structure elements ",
"",
"case opcode of",
" when '0000' rpt = 1; selem = 4; // LD/ST4 (4 registers)",
" when '0010' rpt = 4; selem = 1; // LD/ST1 (4 registers)",
" when '0100' rpt = 1; selem = 3; // LD/ST3 (3 registers)",
" when '0110' rpt = 3; selem = 1; // LD/ST1 (3 registers)",
" when '0111' rpt = 1; selem = 1; // LD/ST1 (1 register)",
" when '1000' rpt = 1; selem = 2; // LD/ST2 (2 registers)",
" when '1010' rpt = 2; selem = 1; // LD/ST1 (2 registers)",
" otherwise UnallocatedEncoding();",
"",
"// .1D format only permitted with LD1 & ST1",
"if size:Q == '110' && selem != 1 then ReservedValue();"
]
},
{
"pattern": "0 Q#1 0 0 1 1 0 0 1 L#1 0 Rm#5 opcode#4 size#2 Rn#5 Rt#5",
"formats": [
{
"condition": "Rm == 11111",
"format": "LD4 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <imm>"
},
{
"condition": "Rm != 11111",
"format": "LD4 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <Xm>"
}
],
"decoder": [
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"boolean wback = TRUE;MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer esize = 8 << UInt(size);",
"integer elements = datasize DIV esize;",
"",
"integer rpt; // number of iterations",
"integer selem; // structure elements ",
"",
"case opcode of",
" when '0000' rpt = 1; selem = 4; // LD/ST4 (4 registers)",
" when '0010' rpt = 4; selem = 1; // LD/ST1 (4 registers)",
" when '0100' rpt = 1; selem = 3; // LD/ST3 (3 registers)",
" when '0110' rpt = 3; selem = 1; // LD/ST1 (3 registers)",
" when '0111' rpt = 1; selem = 1; // LD/ST1 (1 register)",
" when '1000' rpt = 1; selem = 2; // LD/ST2 (2 registers)",
" when '1010' rpt = 2; selem = 1; // LD/ST1 (2 registers)",
" otherwise UnallocatedEncoding();",
"",
"// .1D format only permitted with LD1 & ST1",
"if size:Q == '110' && selem != 1 then ReservedValue();"
]
}
],
"name": "LD4 (multiple structures)",
"description": [
"Load multiple 4-element structures to four registers"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"",
"bits(64) address;",
"bits(64) offs;",
"bits(128) rval;",
"bits(esize) element;",
"integer s;",
"constant integer ebytes = esize DIV 8;",
"",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"offs = Zeros();",
"if replicate then",
" // load and replicate to all elements",
" for s = 0 to selem-1",
" element = Mem[address + offs, ebytes, AccType_VEC];",
" // replicate to fill 128- or 64-bit register",
" V[t] = Replicate(element, datasize DIV esize);",
" offs = offs + ebytes;",
" t = (t + 1) MOD 32;",
"else",
" // load/store one element per register",
" for s = 0 to selem-1",
" rval = V[t];",
" if memop == MemOp_LOAD then",
" // insert into one lane of 128-bit register",
" Elem[rval, index, esize] = Mem[address + offs, ebytes, AccType_VEC];",
" V[t] = rval;",
" else // memop == MemOp_STORE",
" // extract from one lane of 128-bit register",
" Mem[address + offs, ebytes, AccType_VEC] = Elem[rval, index, esize];",
" offs = offs + ebytes;",
" t = (t + 1) MOD 32;",
"",
"if wback then",
" if m != 31 then",
" offs = X[m];",
" if n == 31 then",
" SP[] = address + offs;",
" else",
" X[n] = address + offs;"
],
"variants": [
{
"pattern": "0 Q#1 0 0 1 1 0 1 0 L#1 R#1 0 0 0 0 0 opcode#3 S#1 size#2 Rn#5 Rt#5",
"formats": [
{
"condition": "opcode == 001",
"format": "LD4 { <Vt>.B, <Vt2>.B, <Vt3>.B, <Vt4>.B }[<index>], [<Xn|SP>]"
},
{
"condition": "opcode == 011 && size == x0",
"format": "LD4 { <Vt>.H, <Vt2>.H, <Vt3>.H, <Vt4>.H }[<index>], [<Xn|SP>]"
},
{
"condition": "opcode == 101 && size == 00",
"format": "LD4 { <Vt>.S, <Vt2>.S, <Vt3>.S, <Vt4>.S }[<index>], [<Xn|SP>]"
},
{
"condition": "opcode == 101 && S == 0 && size == 01",
"format": "LD4 { <Vt>.D, <Vt2>.D, <Vt3>.D, <Vt4>.D }[<index>], [<Xn|SP>]"
}
],
"decoder": [
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer m = integer UNKNOWN;",
"boolean wback = FALSE;integer scale = UInt(opcode<2:1>);",
"integer selem = UInt(opcode<0>:R) + 1;",
"boolean replicate = FALSE;",
"integer index;",
"",
"case scale of",
" when 3",
" // load and replicate",
" if L == '0' || S == '1' then UnallocatedEncoding();",
" scale = UInt(size);",
" replicate = TRUE;",
" when 0",
" index = UInt(Q:S:size); // B[0-15]",
" when 1",
" if size<0> == '1' then UnallocatedEncoding();",
" index = UInt(Q:S:size<1>); // H[0-7]",
" when 2",
" if size<1> == '1' then UnallocatedEncoding();",
" if size<0> == '0' then",
" index = UInt(Q:S); // S[0-3]",
" else",
" if S == '1' then UnallocatedEncoding();",
" index = UInt(Q); // D[0-1]",
" scale = 3;",
"",
"MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer esize = 8 << scale;"
]
},
{
"pattern": "0 Q#1 0 0 1 1 0 1 1 L#1 R#1 Rm#5 opcode#3 S#1 size#2 Rn#5 Rt#5",
"formats": [
{
"condition": "Rm == 11111 && opcode == 001",
"format": "LD4 { <Vt>.B, <Vt2>.B, <Vt3>.B, <Vt4>.B }[<index>], [<Xn|SP>], #4"
},
{
"condition": "Rm != 11111 && opcode == 001",
"format": "LD4 { <Vt>.B, <Vt2>.B, <Vt3>.B, <Vt4>.B }[<index>], [<Xn|SP>], <Xm>"
},
{
"condition": "Rm == 11111 && opcode == 011 && size == x0",
"format": "LD4 { <Vt>.H, <Vt2>.H, <Vt3>.H, <Vt4>.H }[<index>], [<Xn|SP>], #8"
},
{
"condition": "Rm != 11111 && opcode == 011 && size == x0",
"format": "LD4 { <Vt>.H, <Vt2>.H, <Vt3>.H, <Vt4>.H }[<index>], [<Xn|SP>], <Xm>"
},
{
"condition": "Rm == 11111 && opcode == 101 && size == 00",
"format": "LD4 { <Vt>.S, <Vt2>.S, <Vt3>.S, <Vt4>.S }[<index>], [<Xn|SP>], #16"
},
{
"condition": "Rm != 11111 && opcode == 101 && size == 00",
"format": "LD4 { <Vt>.S, <Vt2>.S, <Vt3>.S, <Vt4>.S }[<index>], [<Xn|SP>], <Xm>"
},
{
"condition": "Rm == 11111 && opcode == 101 && S == 0 && size == 01",
"format": "LD4 { <Vt>.D, <Vt2>.D, <Vt3>.D, <Vt4>.D }[<index>], [<Xn|SP>], #32"
},
{
"condition": "Rm != 11111 && opcode == 101 && S == 0 && size == 01",
"format": "LD4 { <Vt>.D, <Vt2>.D, <Vt3>.D, <Vt4>.D }[<index>], [<Xn|SP>], <Xm>"
}
],
"decoder": [
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"boolean wback = TRUE;integer scale = UInt(opcode<2:1>);",
"integer selem = UInt(opcode<0>:R) + 1;",
"boolean replicate = FALSE;",
"integer index;",
"",
"case scale of",
" when 3",
" // load and replicate",
" if L == '0' || S == '1' then UnallocatedEncoding();",
" scale = UInt(size);",
" replicate = TRUE;",
" when 0",
" index = UInt(Q:S:size); // B[0-15]",
" when 1",
" if size<0> == '1' then UnallocatedEncoding();",
" index = UInt(Q:S:size<1>); // H[0-7]",
" when 2",
" if size<1> == '1' then UnallocatedEncoding();",
" if size<0> == '0' then",
" index = UInt(Q:S); // S[0-3]",
" else",
" if S == '1' then UnallocatedEncoding();",
" index = UInt(Q); // D[0-1]",
" scale = 3;",
"",
"MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer esize = 8 << scale;"
]
}
],
"name": "LD4 (single structure)",
"description": [
"Load single 4-element structure to one lane of four registers"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"",
"bits(64) address;",
"bits(64) offs;",
"bits(128) rval;",
"bits(esize) element;",
"integer s;",
"constant integer ebytes = esize DIV 8;",
"",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"offs = Zeros();",
"if replicate then",
" // load and replicate to all elements",
" for s = 0 to selem-1",
" element = Mem[address + offs, ebytes, AccType_VEC];",
" // replicate to fill 128- or 64-bit register",
" V[t] = Replicate(element, datasize DIV esize);",
" offs = offs + ebytes;",
" t = (t + 1) MOD 32;",
"else",
" // load/store one element per register",
" for s = 0 to selem-1",
" rval = V[t];",
" if memop == MemOp_LOAD then",
" // insert into one lane of 128-bit register",
" Elem[rval, index, esize] = Mem[address + offs, ebytes, AccType_VEC];",
" V[t] = rval;",
" else // memop == MemOp_STORE",
" // extract from one lane of 128-bit register",
" Mem[address + offs, ebytes, AccType_VEC] = Elem[rval, index, esize];",
" offs = offs + ebytes;",
" t = (t + 1) MOD 32;",
"",
"if wback then",
" if m != 31 then",
" offs = X[m];",
" if n == 31 then",
" SP[] = address + offs;",
" else",
" X[n] = address + offs;"
],
"variants": [
{
"pattern": "0 Q#1 0 0 1 1 0 1 0 L#1 R#1 0 0 0 0 0 opcode#3 S#1 size#2 Rn#5 Rt#5",
"formats": [
{
"condition": null,
"format": "LD4R { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>]"
}
],
"decoder": [
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer m = integer UNKNOWN;",
"boolean wback = FALSE;integer scale = UInt(opcode<2:1>);",
"integer selem = UInt(opcode<0>:R) + 1;",
"boolean replicate = FALSE;",
"integer index;",
"",
"case scale of",
" when 3",
" // load and replicate",
" if L == '0' || S == '1' then UnallocatedEncoding();",
" scale = UInt(size);",
" replicate = TRUE;",
" when 0",
" index = UInt(Q:S:size); // B[0-15]",
" when 1",
" if size<0> == '1' then UnallocatedEncoding();",
" index = UInt(Q:S:size<1>); // H[0-7]",
" when 2",
" if size<1> == '1' then UnallocatedEncoding();",
" if size<0> == '0' then",
" index = UInt(Q:S); // S[0-3]",
" else",
" if S == '1' then UnallocatedEncoding();",
" index = UInt(Q); // D[0-1]",
" scale = 3;",
"",
"MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer esize = 8 << scale;"
]
},
{
"pattern": "0 Q#1 0 0 1 1 0 1 1 L#1 R#1 Rm#5 opcode#3 S#1 size#2 Rn#5 Rt#5",
"formats": [
{
"condition": "Rm == 11111",
"format": "LD4R { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <imm>"
},
{
"condition": "Rm != 11111",
"format": "LD4R { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <Xm>"
}
],
"decoder": [
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"boolean wback = TRUE;integer scale = UInt(opcode<2:1>);",
"integer selem = UInt(opcode<0>:R) + 1;",
"boolean replicate = FALSE;",
"integer index;",
"",
"case scale of",
" when 3",
" // load and replicate",
" if L == '0' || S == '1' then UnallocatedEncoding();",
" scale = UInt(size);",
" replicate = TRUE;",
" when 0",
" index = UInt(Q:S:size); // B[0-15]",
" when 1",
" if size<0> == '1' then UnallocatedEncoding();",
" index = UInt(Q:S:size<1>); // H[0-7]",
" when 2",
" if size<1> == '1' then UnallocatedEncoding();",
" if size<0> == '0' then",
" index = UInt(Q:S); // S[0-3]",
" else",
" if S == '1' then UnallocatedEncoding();",
" index = UInt(Q); // D[0-1]",
" scale = 3;",
"",
"MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"integer datasize = if Q == '1' then 128 else 64;",
"integer esize = 8 << scale;"
]
}
],
"name": "LD4R",
"description": [
"Load single 4-element structure and Replicate to all lanes of four registers"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) value;",
"bits(datasize) data;",
"bits(datasize) result;",
"",
"value = X[s];",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"data = Mem[address, datasize DIV 8, ldacctype];",
"",
"case op of",
" when MemAtomicOp_ADD result = data + value;",
" when MemAtomicOp_BIC result = data AND NOT(value);",
" when MemAtomicOp_EOR result = data EOR value;",
" when MemAtomicOp_ORR result = data OR value;",
" when MemAtomicOp_SMAX result = if SInt(data) > SInt(value) then data else value;",
" when MemAtomicOp_SMIN result = if SInt(data) > SInt(value) then value else data;",
" when MemAtomicOp_UMAX result = if UInt(data) > UInt(value) then data else value;",
" when MemAtomicOp_UMIN result = if UInt(data) > UInt(value) then value else data;",
" when MemAtomicOp_SWP result = value;",
"",
"// All observers in the shareability domain observe the",
"// following load and store atomically.",
"Mem[address, datasize DIV 8, stacctype] = result;",
"",
"X[t] = ZeroExtend(data, regsize);"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 A#1 R#1 1 Rs#5 o3#1 opc#3 0 0 Rn#5 Rt#5",
"formats": [
{
"condition": "size == 10 && A == 1 && R == 0",
"format": "LDADDA <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "size == 10 && A == 1 && R == 1",
"format": "LDADDAL <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "size == 10 && A == 0 && R == 0 && Rt != 11111",
"format": "LDADD <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "size == 10 && A == 0 && R == 1 && Rt != 11111",
"format": "LDADDL <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "size == 11 && A == 1 && R == 0",
"format": "LDADDA <Xs>, <Xt>, [<Xn|SP>]"
},
{
"condition": "size == 11 && A == 1 && R == 1",
"format": "LDADDAL <Xs>, <Xt>, [<Xn|SP>]"
},
{
"condition": "size == 11 && A == 0 && R == 0 && Rt != 11111",
"format": "LDADD <Xs>, <Xt>, [<Xn|SP>]"
},
{
"condition": "size == 11 && A == 0 && R == 1 && Rt != 11111",
"format": "LDADDL <Xs>, <Xt>, [<Xn|SP>]"
}
],
"decoder": [
"if !HaveAtomicExt() then UnallocatedEncoding();",
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer s = UInt(Rs);",
"",
"integer datasize = 8 << UInt(size);",
"integer regsize = if datasize == 64 then 64 else 32;",
"AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"AccType stacctype = if R == '1' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"MemAtomicOp op;",
"case o3:opc of",
" when '0000' op = MemAtomicOp_ADD;",
" when '0001' op = MemAtomicOp_BIC;",
" when '0010' op = MemAtomicOp_EOR;",
" when '0011' op = MemAtomicOp_ORR;",
" when '0100' op = MemAtomicOp_SMAX;",
" when '0101' op = MemAtomicOp_SMIN;",
" when '0110' op = MemAtomicOp_UMAX;",
" when '0111' op = MemAtomicOp_UMIN;",
" when '1000' op = MemAtomicOp_SWP;",
" otherwise UnallocatedEncoding();"
]
}
],
"name": "LDADD, LDADDA, LDADDAL, LDADDL",
"description": [
"Atomic add on word or doubleword in memory"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) value;",
"bits(datasize) data;",
"bits(datasize) result;",
"",
"value = X[s];",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"data = Mem[address, datasize DIV 8, ldacctype];",
"",
"case op of",
" when MemAtomicOp_ADD result = data + value;",
" when MemAtomicOp_BIC result = data AND NOT(value);",
" when MemAtomicOp_EOR result = data EOR value;",
" when MemAtomicOp_ORR result = data OR value;",
" when MemAtomicOp_SMAX result = if SInt(data) > SInt(value) then data else value;",
" when MemAtomicOp_SMIN result = if SInt(data) > SInt(value) then value else data;",
" when MemAtomicOp_UMAX result = if UInt(data) > UInt(value) then data else value;",
" when MemAtomicOp_UMIN result = if UInt(data) > UInt(value) then value else data;",
" when MemAtomicOp_SWP result = value;",
"",
"// All observers in the shareability domain observe the",
"// following load and store atomically.",
"Mem[address, datasize DIV 8, stacctype] = result;",
"",
"X[t] = ZeroExtend(data, regsize);"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 A#1 R#1 1 Rs#5 o3#1 opc#3 0 0 Rn#5 Rt#5",
"formats": [
{
"condition": "A == 1 && R == 0",
"format": "LDADDAB <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 1 && R == 1",
"format": "LDADDALB <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 0 && R == 0 && Rt != 11111",
"format": "LDADDB <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 0 && R == 1 && Rt != 11111",
"format": "LDADDLB <Ws>, <Wt>, [<Xn|SP>]"
}
],
"decoder": [
"if !HaveAtomicExt() then UnallocatedEncoding();",
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer s = UInt(Rs);",
"",
"integer datasize = 8 << UInt(size);",
"integer regsize = if datasize == 64 then 64 else 32;",
"AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"AccType stacctype = if R == '1' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"MemAtomicOp op;",
"case o3:opc of",
" when '0000' op = MemAtomicOp_ADD;",
" when '0001' op = MemAtomicOp_BIC;",
" when '0010' op = MemAtomicOp_EOR;",
" when '0011' op = MemAtomicOp_ORR;",
" when '0100' op = MemAtomicOp_SMAX;",
" when '0101' op = MemAtomicOp_SMIN;",
" when '0110' op = MemAtomicOp_UMAX;",
" when '0111' op = MemAtomicOp_UMIN;",
" when '1000' op = MemAtomicOp_SWP;",
" otherwise UnallocatedEncoding();"
]
}
],
"name": "LDADDB, LDADDAB, LDADDALB, LDADDLB",
"description": [
"Atomic add on byte in memory"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) value;",
"bits(datasize) data;",
"bits(datasize) result;",
"",
"value = X[s];",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"data = Mem[address, datasize DIV 8, ldacctype];",
"",
"case op of",
" when MemAtomicOp_ADD result = data + value;",
" when MemAtomicOp_BIC result = data AND NOT(value);",
" when MemAtomicOp_EOR result = data EOR value;",
" when MemAtomicOp_ORR result = data OR value;",
" when MemAtomicOp_SMAX result = if SInt(data) > SInt(value) then data else value;",
" when MemAtomicOp_SMIN result = if SInt(data) > SInt(value) then value else data;",
" when MemAtomicOp_UMAX result = if UInt(data) > UInt(value) then data else value;",
" when MemAtomicOp_UMIN result = if UInt(data) > UInt(value) then value else data;",
" when MemAtomicOp_SWP result = value;",
"",
"// All observers in the shareability domain observe the",
"// following load and store atomically.",
"Mem[address, datasize DIV 8, stacctype] = result;",
"",
"X[t] = ZeroExtend(data, regsize);"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 A#1 R#1 1 Rs#5 o3#1 opc#3 0 0 Rn#5 Rt#5",
"formats": [
{
"condition": "A == 1 && R == 0",
"format": "LDADDAH <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 1 && R == 1",
"format": "LDADDALH <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 0 && R == 0 && Rt != 11111",
"format": "LDADDH <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 0 && R == 1 && Rt != 11111",
"format": "LDADDLH <Ws>, <Wt>, [<Xn|SP>]"
}
],
"decoder": [
"if !HaveAtomicExt() then UnallocatedEncoding();",
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer s = UInt(Rs);",
"",
"integer datasize = 8 << UInt(size);",
"integer regsize = if datasize == 64 then 64 else 32;",
"AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"AccType stacctype = if R == '1' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"MemAtomicOp op;",
"case o3:opc of",
" when '0000' op = MemAtomicOp_ADD;",
" when '0001' op = MemAtomicOp_BIC;",
" when '0010' op = MemAtomicOp_EOR;",
" when '0011' op = MemAtomicOp_ORR;",
" when '0100' op = MemAtomicOp_SMAX;",
" when '0101' op = MemAtomicOp_SMIN;",
" when '0110' op = MemAtomicOp_UMAX;",
" when '0111' op = MemAtomicOp_UMIN;",
" when '1000' op = MemAtomicOp_SWP;",
" otherwise UnallocatedEncoding();"
]
}
],
"name": "LDADDH, LDADDAH, LDADDALH, LDADDLH",
"description": [
"Atomic add on halfword in memory"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) data;",
"constant integer dbytes = datasize DIV 8;",
"",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"case memop of",
" when MemOp_STORE",
" data = X[t];",
" Mem[address, dbytes, acctype] = data;",
"",
" when MemOp_LOAD",
" data = Mem[address, dbytes, acctype];",
" X[t] = ZeroExtend(data, regsize);"
],
"variants": [
{
"pattern": "size#2 0 0 1 0 0 0 o2#1 L#1 o1#1 Rs#5 o0#1 Rt2#5 Rn#5 Rt#5",
"formats": [
{
"condition": "size == 10",
"format": "LDAR <Wt>, [<Xn|SP>{,#0}]"
},
{
"condition": "size == 11",
"format": "LDAR <Xt>, [<Xn|SP>{,#0}]"
}
],
"decoder": [
"integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"integer t2 = UInt(Rt2); // ignored by load/store single register",
"integer s = UInt(Rs); // ignored by all loads and store-release",
"",
"AccType acctype = if o0 == '0' then AccType_LIMITEDORDERED else AccType_ORDERED;",
"MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"integer elsize = 8 << UInt(size);",
"integer regsize = if elsize == 64 then 64 else 32;",
"integer datasize = elsize;"
]
}
],
"name": "LDAR",
"description": [
"Load-Acquire Register"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) data;",
"constant integer dbytes = datasize DIV 8;",
"",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"case memop of",
" when MemOp_STORE",
" data = X[t];",
" Mem[address, dbytes, acctype] = data;",
"",
" when MemOp_LOAD",
" data = Mem[address, dbytes, acctype];",
" X[t] = ZeroExtend(data, regsize);"
],
"variants": [
{
"pattern": "size#2 0 0 1 0 0 0 o2#1 L#1 o1#1 Rs#5 o0#1 Rt2#5 Rn#5 Rt#5",
"formats": [
{
"condition": null,
"format": "LDARB <Wt>, [<Xn|SP>{,#0}]"
}
],
"decoder": [
"integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"integer t2 = UInt(Rt2); // ignored by load/store single register",
"integer s = UInt(Rs); // ignored by all loads and store-release",
"",
"AccType acctype = if o0 == '0' then AccType_LIMITEDORDERED else AccType_ORDERED;",
"MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"integer elsize = 8 << UInt(size);",
"integer regsize = if elsize == 64 then 64 else 32;",
"integer datasize = elsize;"
]
}
],
"name": "LDARB",
"description": [
"Load-Acquire Register Byte"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) data;",
"constant integer dbytes = datasize DIV 8;",
"",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"case memop of",
" when MemOp_STORE",
" data = X[t];",
" Mem[address, dbytes, acctype] = data;",
"",
" when MemOp_LOAD",
" data = Mem[address, dbytes, acctype];",
" X[t] = ZeroExtend(data, regsize);"
],
"variants": [
{
"pattern": "size#2 0 0 1 0 0 0 o2#1 L#1 o1#1 Rs#5 o0#1 Rt2#5 Rn#5 Rt#5",
"formats": [
{
"condition": null,
"format": "LDARH <Wt>, [<Xn|SP>{,#0}]"
}
],
"decoder": [
"integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"integer t2 = UInt(Rt2); // ignored by load/store single register",
"integer s = UInt(Rs); // ignored by all loads and store-release",
"",
"AccType acctype = if o0 == '0' then AccType_LIMITEDORDERED else AccType_ORDERED;",
"MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"integer elsize = 8 << UInt(size);",
"integer regsize = if elsize == 64 then 64 else 32;",
"integer datasize = elsize;"
]
}
],
"name": "LDARH",
"description": [
"Load-Acquire Register Halfword"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) data;",
"constant integer dbytes = datasize DIV 8;",
"boolean rt_unknown = FALSE;",
"boolean rn_unknown = FALSE;",
"",
"if memop == MemOp_LOAD && pair && t == t2 then",
" Constraint c = ConstrainUnpredictable(Unpredictable_LDPOVERLAP);",
" assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_UNKNOWN rt_unknown = TRUE; // result is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if memop == MemOp_STORE then",
" if s == t || (pair && s == t2) then",
" Constraint c = ConstrainUnpredictable(Unpredictable_DATAOVERLAP);",
" assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_UNKNOWN rt_unknown = TRUE; // store UNKNOWN value",
" when Constraint_NONE rt_unknown = FALSE; // store original value",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
" if s == n && n != 31 then",
" Constraint c = ConstrainUnpredictable(Unpredictable_BASEOVERLAP);",
" assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_UNKNOWN rn_unknown = TRUE; // address is UNKNOWN",
" when Constraint_NONE rn_unknown = FALSE; // address is original base",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"elsif rn_unknown then",
" address = bits(64) UNKNOWN;",
"else",
" address = X[n];",
"",
"case memop of",
" when MemOp_STORE",
" if rt_unknown then",
" data = bits(datasize) UNKNOWN;",
" elsif pair then",
" bits(datasize DIV 2) el1 = X[t];",
" bits(datasize DIV 2) el2 = X[t2];",
" data = if BigEndian() then el1 : el2 else el2 : el1;",
" else",
" data = X[t];",
"",
" bit status = '1';",
" // Check whether the Exclusive Monitors are set to include the",
" // physical memory locations corresponding to virtual address",
" // range [address, address+dbytes-1].",
" if AArch64.ExclusiveMonitorsPass(address, dbytes) then",
" // This atomic write will be rejected if it does not refer",
" // to the same physical locations after address translation.",
" Mem[address, dbytes, acctype] = data;",
" status = ExclusiveMonitorsStatus();",
" X[s] = ZeroExtend(status, 32);",
"",
" when MemOp_LOAD",
" // Tell the Exclusive Monitors to record a sequence of one or more atomic",
" // memory reads from virtual address range [address, address+dbytes-1].",
" // The Exclusive Monitor will only be set if all the reads are from the",
" // same dbytes-aligned physical address, to allow for the possibility of",
" // an atomicity break if the translation is changed between reads.",
" AArch64.SetExclusiveMonitors(address, dbytes);",
"",
" if pair then",
" if rt_unknown then",
" // ConstrainedUNPREDICTABLE case",
" X[t] = bits(datasize) UNKNOWN;",
" elsif elsize == 32 then",
" // 32-bit load exclusive pair (atomic)",
" data = Mem[address, dbytes, acctype];",
" if BigEndian() then",
" X[t] = data;",
" X[t2] = data;",
" else",
" X[t] = data;",
" X[t2] = data;",
" else // elsize == 64",
" // 64-bit load exclusive pair (not atomic),",
" // but must be 128-bit aligned",
" if address != Align(address, dbytes) then",
" iswrite = FALSE;",
" secondstage = FALSE;",
" AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage));",
" X[t] = Mem[address + 0, 8, acctype];",
" X[t2] = Mem[address + 8, 8, acctype];",
" else",
" data = Mem[address, dbytes, acctype];",
" X[t] = ZeroExtend(data, regsize);"
],
"variants": [
{
"pattern": "1 sz#1 0 0 1 0 0 0 o2#1 L#1 o1#1 Rs#5 o0#1 Rt2#5 Rn#5 Rt#5",
"formats": [
{
"condition": "sz == 0",
"format": "LDAXP <Wt1>, <Wt2>, [<Xn|SP>{,#0}]"
},
{
"condition": "sz == 1",
"format": "LDAXP <Xt1>, <Xt2>, [<Xn|SP>{,#0}]"
}
],
"decoder": [
"integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"integer t2 = UInt(Rt2); // ignored by load/store single register",
"integer s = UInt(Rs); // ignored by all loads and store-release",
"",
"AccType acctype = if o0 == '1' then AccType_ORDERED else AccType_ATOMIC;",
"boolean pair = TRUE;",
"MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"integer elsize = 32 << UInt(sz);",
"integer regsize = if elsize == 64 then 64 else 32;",
"integer datasize = if pair then elsize * 2 else elsize;"
]
}
],
"name": "LDAXP",
"description": [
"Load-Acquire Exclusive Pair of Registers"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) data;",
"constant integer dbytes = datasize DIV 8;",
"boolean rt_unknown = FALSE;",
"boolean rn_unknown = FALSE;",
"",
"if memop == MemOp_LOAD && pair && t == t2 then",
" Constraint c = ConstrainUnpredictable(Unpredictable_LDPOVERLAP);",
" assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_UNKNOWN rt_unknown = TRUE; // result is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if memop == MemOp_STORE then",
" if s == t || (pair && s == t2) then",
" Constraint c = ConstrainUnpredictable(Unpredictable_DATAOVERLAP);",
" assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_UNKNOWN rt_unknown = TRUE; // store UNKNOWN value",
" when Constraint_NONE rt_unknown = FALSE; // store original value",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
" if s == n && n != 31 then",
" Constraint c = ConstrainUnpredictable(Unpredictable_BASEOVERLAP);",
" assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_UNKNOWN rn_unknown = TRUE; // address is UNKNOWN",
" when Constraint_NONE rn_unknown = FALSE; // address is original base",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"elsif rn_unknown then",
" address = bits(64) UNKNOWN;",
"else",
" address = X[n];",
"",
"case memop of",
" when MemOp_STORE",
" if rt_unknown then",
" data = bits(datasize) UNKNOWN;",
" elsif pair then",
" bits(datasize DIV 2) el1 = X[t];",
" bits(datasize DIV 2) el2 = X[t2];",
" data = if BigEndian() then el1 : el2 else el2 : el1;",
" else",
" data = X[t];",
"",
" bit status = '1';",
" // Check whether the Exclusive Monitors are set to include the",
" // physical memory locations corresponding to virtual address",
" // range [address, address+dbytes-1].",
" if AArch64.ExclusiveMonitorsPass(address, dbytes) then",
" // This atomic write will be rejected if it does not refer",
" // to the same physical locations after address translation.",
" Mem[address, dbytes, acctype] = data;",
" status = ExclusiveMonitorsStatus();",
" X[s] = ZeroExtend(status, 32);",
"",
" when MemOp_LOAD",
" // Tell the Exclusive Monitors to record a sequence of one or more atomic",
" // memory reads from virtual address range [address, address+dbytes-1].",
" // The Exclusive Monitor will only be set if all the reads are from the",
" // same dbytes-aligned physical address, to allow for the possibility of",
" // an atomicity break if the translation is changed between reads.",
" AArch64.SetExclusiveMonitors(address, dbytes);",
"",
" if pair then",
" if rt_unknown then",
" // ConstrainedUNPREDICTABLE case",
" X[t] = bits(datasize) UNKNOWN;",
" elsif elsize == 32 then",
" // 32-bit load exclusive pair (atomic)",
" data = Mem[address, dbytes, acctype];",
" if BigEndian() then",
" X[t] = data;",
" X[t2] = data;",
" else",
" X[t] = data;",
" X[t2] = data;",
" else // elsize == 64",
" // 64-bit load exclusive pair (not atomic),",
" // but must be 128-bit aligned",
" if address != Align(address, dbytes) then",
" iswrite = FALSE;",
" secondstage = FALSE;",
" AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage));",
" X[t] = Mem[address + 0, 8, acctype];",
" X[t2] = Mem[address + 8, 8, acctype];",
" else",
" data = Mem[address, dbytes, acctype];",
" X[t] = ZeroExtend(data, regsize);"
],
"variants": [
{
"pattern": "size#2 0 0 1 0 0 0 o2#1 L#1 o1#1 Rs#5 o0#1 Rt2#5 Rn#5 Rt#5",
"formats": [
{
"condition": "size == 10",
"format": "LDAXR <Wt>, [<Xn|SP>{,#0}]"
},
{
"condition": "size == 11",
"format": "LDAXR <Xt>, [<Xn|SP>{,#0}]"
}
],
"decoder": [
"integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"integer t2 = UInt(Rt2); // ignored by load/store single register",
"integer s = UInt(Rs); // ignored by all loads and store-release",
"",
"AccType acctype = if o0 == '1' then AccType_ORDERED else AccType_ATOMIC;",
"boolean pair = FALSE;",
"MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"integer elsize = 8 << UInt(size);",
"integer regsize = if elsize == 64 then 64 else 32;",
"integer datasize = if pair then elsize * 2 else elsize;"
]
}
],
"name": "LDAXR",
"description": [
"Load-Acquire Exclusive Register"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) data;",
"constant integer dbytes = datasize DIV 8;",
"boolean rt_unknown = FALSE;",
"boolean rn_unknown = FALSE;",
"",
"if memop == MemOp_LOAD && pair && t == t2 then",
" Constraint c = ConstrainUnpredictable(Unpredictable_LDPOVERLAP);",
" assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_UNKNOWN rt_unknown = TRUE; // result is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if memop == MemOp_STORE then",
" if s == t || (pair && s == t2) then",
" Constraint c = ConstrainUnpredictable(Unpredictable_DATAOVERLAP);",
" assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_UNKNOWN rt_unknown = TRUE; // store UNKNOWN value",
" when Constraint_NONE rt_unknown = FALSE; // store original value",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
" if s == n && n != 31 then",
" Constraint c = ConstrainUnpredictable(Unpredictable_BASEOVERLAP);",
" assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_UNKNOWN rn_unknown = TRUE; // address is UNKNOWN",
" when Constraint_NONE rn_unknown = FALSE; // address is original base",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"elsif rn_unknown then",
" address = bits(64) UNKNOWN;",
"else",
" address = X[n];",
"",
"case memop of",
" when MemOp_STORE",
" if rt_unknown then",
" data = bits(datasize) UNKNOWN;",
" elsif pair then",
" bits(datasize DIV 2) el1 = X[t];",
" bits(datasize DIV 2) el2 = X[t2];",
" data = if BigEndian() then el1 : el2 else el2 : el1;",
" else",
" data = X[t];",
"",
" bit status = '1';",
" // Check whether the Exclusive Monitors are set to include the",
" // physical memory locations corresponding to virtual address",
" // range [address, address+dbytes-1].",
" if AArch64.ExclusiveMonitorsPass(address, dbytes) then",
" // This atomic write will be rejected if it does not refer",
" // to the same physical locations after address translation.",
" Mem[address, dbytes, acctype] = data;",
" status = ExclusiveMonitorsStatus();",
" X[s] = ZeroExtend(status, 32);",
"",
" when MemOp_LOAD",
" // Tell the Exclusive Monitors to record a sequence of one or more atomic",
" // memory reads from virtual address range [address, address+dbytes-1].",
" // The Exclusive Monitor will only be set if all the reads are from the",
" // same dbytes-aligned physical address, to allow for the possibility of",
" // an atomicity break if the translation is changed between reads.",
" AArch64.SetExclusiveMonitors(address, dbytes);",
"",
" if pair then",
" if rt_unknown then",
" // ConstrainedUNPREDICTABLE case",
" X[t] = bits(datasize) UNKNOWN;",
" elsif elsize == 32 then",
" // 32-bit load exclusive pair (atomic)",
" data = Mem[address, dbytes, acctype];",
" if BigEndian() then",
" X[t] = data;",
" X[t2] = data;",
" else",
" X[t] = data;",
" X[t2] = data;",
" else // elsize == 64",
" // 64-bit load exclusive pair (not atomic),",
" // but must be 128-bit aligned",
" if address != Align(address, dbytes) then",
" iswrite = FALSE;",
" secondstage = FALSE;",
" AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage));",
" X[t] = Mem[address + 0, 8, acctype];",
" X[t2] = Mem[address + 8, 8, acctype];",
" else",
" data = Mem[address, dbytes, acctype];",
" X[t] = ZeroExtend(data, regsize);"
],
"variants": [
{
"pattern": "size#2 0 0 1 0 0 0 o2#1 L#1 o1#1 Rs#5 o0#1 Rt2#5 Rn#5 Rt#5",
"formats": [
{
"condition": null,
"format": "LDAXRB <Wt>, [<Xn|SP>{,#0}]"
}
],
"decoder": [
"integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"integer t2 = UInt(Rt2); // ignored by load/store single register",
"integer s = UInt(Rs); // ignored by all loads and store-release",
"",
"AccType acctype = if o0 == '1' then AccType_ORDERED else AccType_ATOMIC;",
"boolean pair = FALSE;",
"MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"integer elsize = 8 << UInt(size);",
"integer regsize = if elsize == 64 then 64 else 32;",
"integer datasize = if pair then elsize * 2 else elsize;"
]
}
],
"name": "LDAXRB",
"description": [
"Load-Acquire Exclusive Register Byte"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) data;",
"constant integer dbytes = datasize DIV 8;",
"boolean rt_unknown = FALSE;",
"boolean rn_unknown = FALSE;",
"",
"if memop == MemOp_LOAD && pair && t == t2 then",
" Constraint c = ConstrainUnpredictable(Unpredictable_LDPOVERLAP);",
" assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_UNKNOWN rt_unknown = TRUE; // result is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if memop == MemOp_STORE then",
" if s == t || (pair && s == t2) then",
" Constraint c = ConstrainUnpredictable(Unpredictable_DATAOVERLAP);",
" assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_UNKNOWN rt_unknown = TRUE; // store UNKNOWN value",
" when Constraint_NONE rt_unknown = FALSE; // store original value",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
" if s == n && n != 31 then",
" Constraint c = ConstrainUnpredictable(Unpredictable_BASEOVERLAP);",
" assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_UNKNOWN rn_unknown = TRUE; // address is UNKNOWN",
" when Constraint_NONE rn_unknown = FALSE; // address is original base",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"elsif rn_unknown then",
" address = bits(64) UNKNOWN;",
"else",
" address = X[n];",
"",
"case memop of",
" when MemOp_STORE",
" if rt_unknown then",
" data = bits(datasize) UNKNOWN;",
" elsif pair then",
" bits(datasize DIV 2) el1 = X[t];",
" bits(datasize DIV 2) el2 = X[t2];",
" data = if BigEndian() then el1 : el2 else el2 : el1;",
" else",
" data = X[t];",
"",
" bit status = '1';",
" // Check whether the Exclusive Monitors are set to include the",
" // physical memory locations corresponding to virtual address",
" // range [address, address+dbytes-1].",
" if AArch64.ExclusiveMonitorsPass(address, dbytes) then",
" // This atomic write will be rejected if it does not refer",
" // to the same physical locations after address translation.",
" Mem[address, dbytes, acctype] = data;",
" status = ExclusiveMonitorsStatus();",
" X[s] = ZeroExtend(status, 32);",
"",
" when MemOp_LOAD",
" // Tell the Exclusive Monitors to record a sequence of one or more atomic",
" // memory reads from virtual address range [address, address+dbytes-1].",
" // The Exclusive Monitor will only be set if all the reads are from the",
" // same dbytes-aligned physical address, to allow for the possibility of",
" // an atomicity break if the translation is changed between reads.",
" AArch64.SetExclusiveMonitors(address, dbytes);",
"",
" if pair then",
" if rt_unknown then",
" // ConstrainedUNPREDICTABLE case",
" X[t] = bits(datasize) UNKNOWN;",
" elsif elsize == 32 then",
" // 32-bit load exclusive pair (atomic)",
" data = Mem[address, dbytes, acctype];",
" if BigEndian() then",
" X[t] = data;",
" X[t2] = data;",
" else",
" X[t] = data;",
" X[t2] = data;",
" else // elsize == 64",
" // 64-bit load exclusive pair (not atomic),",
" // but must be 128-bit aligned",
" if address != Align(address, dbytes) then",
" iswrite = FALSE;",
" secondstage = FALSE;",
" AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage));",
" X[t] = Mem[address + 0, 8, acctype];",
" X[t2] = Mem[address + 8, 8, acctype];",
" else",
" data = Mem[address, dbytes, acctype];",
" X[t] = ZeroExtend(data, regsize);"
],
"variants": [
{
"pattern": "size#2 0 0 1 0 0 0 o2#1 L#1 o1#1 Rs#5 o0#1 Rt2#5 Rn#5 Rt#5",
"formats": [
{
"condition": null,
"format": "LDAXRH <Wt>, [<Xn|SP>{,#0}]"
}
],
"decoder": [
"integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"integer t2 = UInt(Rt2); // ignored by load/store single register",
"integer s = UInt(Rs); // ignored by all loads and store-release",
"",
"AccType acctype = if o0 == '1' then AccType_ORDERED else AccType_ATOMIC;",
"boolean pair = FALSE;",
"MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"integer elsize = 8 << UInt(size);",
"integer regsize = if elsize == 64 then 64 else 32;",
"integer datasize = if pair then elsize * 2 else elsize;"
]
}
],
"name": "LDAXRH",
"description": [
"Load-Acquire Exclusive Register Halfword"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) value;",
"bits(datasize) data;",
"bits(datasize) result;",
"",
"value = X[s];",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"data = Mem[address, datasize DIV 8, ldacctype];",
"",
"case op of",
" when MemAtomicOp_ADD result = data + value;",
" when MemAtomicOp_BIC result = data AND NOT(value);",
" when MemAtomicOp_EOR result = data EOR value;",
" when MemAtomicOp_ORR result = data OR value;",
" when MemAtomicOp_SMAX result = if SInt(data) > SInt(value) then data else value;",
" when MemAtomicOp_SMIN result = if SInt(data) > SInt(value) then value else data;",
" when MemAtomicOp_UMAX result = if UInt(data) > UInt(value) then data else value;",
" when MemAtomicOp_UMIN result = if UInt(data) > UInt(value) then value else data;",
" when MemAtomicOp_SWP result = value;",
"",
"// All observers in the shareability domain observe the",
"// following load and store atomically.",
"Mem[address, datasize DIV 8, stacctype] = result;",
"",
"X[t] = ZeroExtend(data, regsize);"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 A#1 R#1 1 Rs#5 o3#1 opc#3 0 0 Rn#5 Rt#5",
"formats": [
{
"condition": "size == 10 && A == 1 && R == 0",
"format": "LDCLRA <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "size == 10 && A == 1 && R == 1",
"format": "LDCLRAL <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "size == 10 && A == 0 && R == 0 && Rt != 11111",
"format": "LDCLR <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "size == 10 && A == 0 && R == 1 && Rt != 11111",
"format": "LDCLRL <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "size == 11 && A == 1 && R == 0",
"format": "LDCLRA <Xs>, <Xt>, [<Xn|SP>]"
},
{
"condition": "size == 11 && A == 1 && R == 1",
"format": "LDCLRAL <Xs>, <Xt>, [<Xn|SP>]"
},
{
"condition": "size == 11 && A == 0 && R == 0 && Rt != 11111",
"format": "LDCLR <Xs>, <Xt>, [<Xn|SP>]"
},
{
"condition": "size == 11 && A == 0 && R == 1 && Rt != 11111",
"format": "LDCLRL <Xs>, <Xt>, [<Xn|SP>]"
}
],
"decoder": [
"if !HaveAtomicExt() then UnallocatedEncoding();",
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer s = UInt(Rs);",
"",
"integer datasize = 8 << UInt(size);",
"integer regsize = if datasize == 64 then 64 else 32;",
"AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"AccType stacctype = if R == '1' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"MemAtomicOp op;",
"case o3:opc of",
" when '0000' op = MemAtomicOp_ADD;",
" when '0001' op = MemAtomicOp_BIC;",
" when '0010' op = MemAtomicOp_EOR;",
" when '0011' op = MemAtomicOp_ORR;",
" when '0100' op = MemAtomicOp_SMAX;",
" when '0101' op = MemAtomicOp_SMIN;",
" when '0110' op = MemAtomicOp_UMAX;",
" when '0111' op = MemAtomicOp_UMIN;",
" when '1000' op = MemAtomicOp_SWP;",
" otherwise UnallocatedEncoding();"
]
}
],
"name": "LDCLR, LDCLRA, LDCLRAL, LDCLRL",
"description": [
"Atomic bit clear on word or doubleword in memory"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) value;",
"bits(datasize) data;",
"bits(datasize) result;",
"",
"value = X[s];",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"data = Mem[address, datasize DIV 8, ldacctype];",
"",
"case op of",
" when MemAtomicOp_ADD result = data + value;",
" when MemAtomicOp_BIC result = data AND NOT(value);",
" when MemAtomicOp_EOR result = data EOR value;",
" when MemAtomicOp_ORR result = data OR value;",
" when MemAtomicOp_SMAX result = if SInt(data) > SInt(value) then data else value;",
" when MemAtomicOp_SMIN result = if SInt(data) > SInt(value) then value else data;",
" when MemAtomicOp_UMAX result = if UInt(data) > UInt(value) then data else value;",
" when MemAtomicOp_UMIN result = if UInt(data) > UInt(value) then value else data;",
" when MemAtomicOp_SWP result = value;",
"",
"// All observers in the shareability domain observe the",
"// following load and store atomically.",
"Mem[address, datasize DIV 8, stacctype] = result;",
"",
"X[t] = ZeroExtend(data, regsize);"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 A#1 R#1 1 Rs#5 o3#1 opc#3 0 0 Rn#5 Rt#5",
"formats": [
{
"condition": "A == 1 && R == 0",
"format": "LDCLRAB <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 1 && R == 1",
"format": "LDCLRALB <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 0 && R == 0 && Rt != 11111",
"format": "LDCLRB <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 0 && R == 1 && Rt != 11111",
"format": "LDCLRLB <Ws>, <Wt>, [<Xn|SP>]"
}
],
"decoder": [
"if !HaveAtomicExt() then UnallocatedEncoding();",
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer s = UInt(Rs);",
"",
"integer datasize = 8 << UInt(size);",
"integer regsize = if datasize == 64 then 64 else 32;",
"AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"AccType stacctype = if R == '1' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"MemAtomicOp op;",
"case o3:opc of",
" when '0000' op = MemAtomicOp_ADD;",
" when '0001' op = MemAtomicOp_BIC;",
" when '0010' op = MemAtomicOp_EOR;",
" when '0011' op = MemAtomicOp_ORR;",
" when '0100' op = MemAtomicOp_SMAX;",
" when '0101' op = MemAtomicOp_SMIN;",
" when '0110' op = MemAtomicOp_UMAX;",
" when '0111' op = MemAtomicOp_UMIN;",
" when '1000' op = MemAtomicOp_SWP;",
" otherwise UnallocatedEncoding();"
]
}
],
"name": "LDCLRB, LDCLRAB, LDCLRALB, LDCLRLB",
"description": [
"Atomic bit clear on byte in memory"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) value;",
"bits(datasize) data;",
"bits(datasize) result;",
"",
"value = X[s];",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"data = Mem[address, datasize DIV 8, ldacctype];",
"",
"case op of",
" when MemAtomicOp_ADD result = data + value;",
" when MemAtomicOp_BIC result = data AND NOT(value);",
" when MemAtomicOp_EOR result = data EOR value;",
" when MemAtomicOp_ORR result = data OR value;",
" when MemAtomicOp_SMAX result = if SInt(data) > SInt(value) then data else value;",
" when MemAtomicOp_SMIN result = if SInt(data) > SInt(value) then value else data;",
" when MemAtomicOp_UMAX result = if UInt(data) > UInt(value) then data else value;",
" when MemAtomicOp_UMIN result = if UInt(data) > UInt(value) then value else data;",
" when MemAtomicOp_SWP result = value;",
"",
"// All observers in the shareability domain observe the",
"// following load and store atomically.",
"Mem[address, datasize DIV 8, stacctype] = result;",
"",
"X[t] = ZeroExtend(data, regsize);"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 A#1 R#1 1 Rs#5 o3#1 opc#3 0 0 Rn#5 Rt#5",
"formats": [
{
"condition": "A == 1 && R == 0",
"format": "LDCLRAH <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 1 && R == 1",
"format": "LDCLRALH <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 0 && R == 0 && Rt != 11111",
"format": "LDCLRH <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 0 && R == 1 && Rt != 11111",
"format": "LDCLRLH <Ws>, <Wt>, [<Xn|SP>]"
}
],
"decoder": [
"if !HaveAtomicExt() then UnallocatedEncoding();",
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer s = UInt(Rs);",
"",
"integer datasize = 8 << UInt(size);",
"integer regsize = if datasize == 64 then 64 else 32;",
"AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"AccType stacctype = if R == '1' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"MemAtomicOp op;",
"case o3:opc of",
" when '0000' op = MemAtomicOp_ADD;",
" when '0001' op = MemAtomicOp_BIC;",
" when '0010' op = MemAtomicOp_EOR;",
" when '0011' op = MemAtomicOp_ORR;",
" when '0100' op = MemAtomicOp_SMAX;",
" when '0101' op = MemAtomicOp_SMIN;",
" when '0110' op = MemAtomicOp_UMAX;",
" when '0111' op = MemAtomicOp_UMIN;",
" when '1000' op = MemAtomicOp_SWP;",
" otherwise UnallocatedEncoding();"
]
}
],
"name": "LDCLRH, LDCLRAH, LDCLRALH, LDCLRLH",
"description": [
"Atomic bit clear on halfword in memory"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) value;",
"bits(datasize) data;",
"bits(datasize) result;",
"",
"value = X[s];",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"data = Mem[address, datasize DIV 8, ldacctype];",
"",
"case op of",
" when MemAtomicOp_ADD result = data + value;",
" when MemAtomicOp_BIC result = data AND NOT(value);",
" when MemAtomicOp_EOR result = data EOR value;",
" when MemAtomicOp_ORR result = data OR value;",
" when MemAtomicOp_SMAX result = if SInt(data) > SInt(value) then data else value;",
" when MemAtomicOp_SMIN result = if SInt(data) > SInt(value) then value else data;",
" when MemAtomicOp_UMAX result = if UInt(data) > UInt(value) then data else value;",
" when MemAtomicOp_UMIN result = if UInt(data) > UInt(value) then value else data;",
" when MemAtomicOp_SWP result = value;",
"",
"// All observers in the shareability domain observe the",
"// following load and store atomically.",
"Mem[address, datasize DIV 8, stacctype] = result;",
"",
"X[t] = ZeroExtend(data, regsize);"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 A#1 R#1 1 Rs#5 o3#1 opc#3 0 0 Rn#5 Rt#5",
"formats": [
{
"condition": "size == 10 && A == 1 && R == 0",
"format": "LDEORA <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "size == 10 && A == 1 && R == 1",
"format": "LDEORAL <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "size == 10 && A == 0 && R == 0 && Rt != 11111",
"format": "LDEOR <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "size == 10 && A == 0 && R == 1 && Rt != 11111",
"format": "LDEORL <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "size == 11 && A == 1 && R == 0",
"format": "LDEORA <Xs>, <Xt>, [<Xn|SP>]"
},
{
"condition": "size == 11 && A == 1 && R == 1",
"format": "LDEORAL <Xs>, <Xt>, [<Xn|SP>]"
},
{
"condition": "size == 11 && A == 0 && R == 0 && Rt != 11111",
"format": "LDEOR <Xs>, <Xt>, [<Xn|SP>]"
},
{
"condition": "size == 11 && A == 0 && R == 1 && Rt != 11111",
"format": "LDEORL <Xs>, <Xt>, [<Xn|SP>]"
}
],
"decoder": [
"if !HaveAtomicExt() then UnallocatedEncoding();",
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer s = UInt(Rs);",
"",
"integer datasize = 8 << UInt(size);",
"integer regsize = if datasize == 64 then 64 else 32;",
"AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"AccType stacctype = if R == '1' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"MemAtomicOp op;",
"case o3:opc of",
" when '0000' op = MemAtomicOp_ADD;",
" when '0001' op = MemAtomicOp_BIC;",
" when '0010' op = MemAtomicOp_EOR;",
" when '0011' op = MemAtomicOp_ORR;",
" when '0100' op = MemAtomicOp_SMAX;",
" when '0101' op = MemAtomicOp_SMIN;",
" when '0110' op = MemAtomicOp_UMAX;",
" when '0111' op = MemAtomicOp_UMIN;",
" when '1000' op = MemAtomicOp_SWP;",
" otherwise UnallocatedEncoding();"
]
}
],
"name": "LDEOR, LDEORA, LDEORAL, LDEORL",
"description": [
"Atomic exclusive OR on word or doubleword in memory"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) value;",
"bits(datasize) data;",
"bits(datasize) result;",
"",
"value = X[s];",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"data = Mem[address, datasize DIV 8, ldacctype];",
"",
"case op of",
" when MemAtomicOp_ADD result = data + value;",
" when MemAtomicOp_BIC result = data AND NOT(value);",
" when MemAtomicOp_EOR result = data EOR value;",
" when MemAtomicOp_ORR result = data OR value;",
" when MemAtomicOp_SMAX result = if SInt(data) > SInt(value) then data else value;",
" when MemAtomicOp_SMIN result = if SInt(data) > SInt(value) then value else data;",
" when MemAtomicOp_UMAX result = if UInt(data) > UInt(value) then data else value;",
" when MemAtomicOp_UMIN result = if UInt(data) > UInt(value) then value else data;",
" when MemAtomicOp_SWP result = value;",
"",
"// All observers in the shareability domain observe the",
"// following load and store atomically.",
"Mem[address, datasize DIV 8, stacctype] = result;",
"",
"X[t] = ZeroExtend(data, regsize);"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 A#1 R#1 1 Rs#5 o3#1 opc#3 0 0 Rn#5 Rt#5",
"formats": [
{
"condition": "A == 1 && R == 0",
"format": "LDEORAB <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 1 && R == 1",
"format": "LDEORALB <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 0 && R == 0 && Rt != 11111",
"format": "LDEORB <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 0 && R == 1 && Rt != 11111",
"format": "LDEORLB <Ws>, <Wt>, [<Xn|SP>]"
}
],
"decoder": [
"if !HaveAtomicExt() then UnallocatedEncoding();",
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer s = UInt(Rs);",
"",
"integer datasize = 8 << UInt(size);",
"integer regsize = if datasize == 64 then 64 else 32;",
"AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"AccType stacctype = if R == '1' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"MemAtomicOp op;",
"case o3:opc of",
" when '0000' op = MemAtomicOp_ADD;",
" when '0001' op = MemAtomicOp_BIC;",
" when '0010' op = MemAtomicOp_EOR;",
" when '0011' op = MemAtomicOp_ORR;",
" when '0100' op = MemAtomicOp_SMAX;",
" when '0101' op = MemAtomicOp_SMIN;",
" when '0110' op = MemAtomicOp_UMAX;",
" when '0111' op = MemAtomicOp_UMIN;",
" when '1000' op = MemAtomicOp_SWP;",
" otherwise UnallocatedEncoding();"
]
}
],
"name": "LDEORB, LDEORAB, LDEORALB, LDEORLB",
"description": [
"Atomic exclusive OR on byte in memory"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) value;",
"bits(datasize) data;",
"bits(datasize) result;",
"",
"value = X[s];",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"data = Mem[address, datasize DIV 8, ldacctype];",
"",
"case op of",
" when MemAtomicOp_ADD result = data + value;",
" when MemAtomicOp_BIC result = data AND NOT(value);",
" when MemAtomicOp_EOR result = data EOR value;",
" when MemAtomicOp_ORR result = data OR value;",
" when MemAtomicOp_SMAX result = if SInt(data) > SInt(value) then data else value;",
" when MemAtomicOp_SMIN result = if SInt(data) > SInt(value) then value else data;",
" when MemAtomicOp_UMAX result = if UInt(data) > UInt(value) then data else value;",
" when MemAtomicOp_UMIN result = if UInt(data) > UInt(value) then value else data;",
" when MemAtomicOp_SWP result = value;",
"",
"// All observers in the shareability domain observe the",
"// following load and store atomically.",
"Mem[address, datasize DIV 8, stacctype] = result;",
"",
"X[t] = ZeroExtend(data, regsize);"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 A#1 R#1 1 Rs#5 o3#1 opc#3 0 0 Rn#5 Rt#5",
"formats": [
{
"condition": "A == 1 && R == 0",
"format": "LDEORAH <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 1 && R == 1",
"format": "LDEORALH <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 0 && R == 0 && Rt != 11111",
"format": "LDEORH <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 0 && R == 1 && Rt != 11111",
"format": "LDEORLH <Ws>, <Wt>, [<Xn|SP>]"
}
],
"decoder": [
"if !HaveAtomicExt() then UnallocatedEncoding();",
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer s = UInt(Rs);",
"",
"integer datasize = 8 << UInt(size);",
"integer regsize = if datasize == 64 then 64 else 32;",
"AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"AccType stacctype = if R == '1' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"MemAtomicOp op;",
"case o3:opc of",
" when '0000' op = MemAtomicOp_ADD;",
" when '0001' op = MemAtomicOp_BIC;",
" when '0010' op = MemAtomicOp_EOR;",
" when '0011' op = MemAtomicOp_ORR;",
" when '0100' op = MemAtomicOp_SMAX;",
" when '0101' op = MemAtomicOp_SMIN;",
" when '0110' op = MemAtomicOp_UMAX;",
" when '0111' op = MemAtomicOp_UMIN;",
" when '1000' op = MemAtomicOp_SWP;",
" otherwise UnallocatedEncoding();"
]
}
],
"name": "LDEORH, LDEORAH, LDEORALH, LDEORLH",
"description": [
"Atomic exclusive OR on halfword in memory"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) data;",
"constant integer dbytes = datasize DIV 8;",
"",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"case memop of",
" when MemOp_STORE",
" data = X[t];",
" Mem[address, dbytes, acctype] = data;",
"",
" when MemOp_LOAD",
" data = Mem[address, dbytes, acctype];",
" X[t] = ZeroExtend(data, regsize);"
],
"variants": [
{
"pattern": "size#2 0 0 1 0 0 0 o2#1 L#1 o1#1 Rs#5 o0#1 Rt2#5 Rn#5 Rt#5",
"formats": [
{
"condition": "size == 10",
"format": "LDLAR <Wt>, [<Xn|SP>{,#0}]"
},
{
"condition": "size == 11",
"format": "LDLAR <Xt>, [<Xn|SP>{,#0}]"
}
],
"decoder": [
"integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"integer t2 = UInt(Rt2); // ignored by load/store single register",
"integer s = UInt(Rs); // ignored by all loads and store-release",
"",
"AccType acctype = if o0 == '0' then AccType_LIMITEDORDERED else AccType_ORDERED;",
"MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"integer elsize = 8 << UInt(size);",
"integer regsize = if elsize == 64 then 64 else 32;",
"integer datasize = elsize;"
]
}
],
"name": "LDLAR",
"description": [
"Load LOAcquire Register"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) data;",
"constant integer dbytes = datasize DIV 8;",
"",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"case memop of",
" when MemOp_STORE",
" data = X[t];",
" Mem[address, dbytes, acctype] = data;",
"",
" when MemOp_LOAD",
" data = Mem[address, dbytes, acctype];",
" X[t] = ZeroExtend(data, regsize);"
],
"variants": [
{
"pattern": "size#2 0 0 1 0 0 0 o2#1 L#1 o1#1 Rs#5 o0#1 Rt2#5 Rn#5 Rt#5",
"formats": [
{
"condition": null,
"format": "LDLARB <Wt>, [<Xn|SP>{,#0}]"
}
],
"decoder": [
"integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"integer t2 = UInt(Rt2); // ignored by load/store single register",
"integer s = UInt(Rs); // ignored by all loads and store-release",
"",
"AccType acctype = if o0 == '0' then AccType_LIMITEDORDERED else AccType_ORDERED;",
"MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"integer elsize = 8 << UInt(size);",
"integer regsize = if elsize == 64 then 64 else 32;",
"integer datasize = elsize;"
]
}
],
"name": "LDLARB",
"description": [
"Load LOAcquire Register Byte"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) data;",
"constant integer dbytes = datasize DIV 8;",
"",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"case memop of",
" when MemOp_STORE",
" data = X[t];",
" Mem[address, dbytes, acctype] = data;",
"",
" when MemOp_LOAD",
" data = Mem[address, dbytes, acctype];",
" X[t] = ZeroExtend(data, regsize);"
],
"variants": [
{
"pattern": "size#2 0 0 1 0 0 0 o2#1 L#1 o1#1 Rs#5 o0#1 Rt2#5 Rn#5 Rt#5",
"formats": [
{
"condition": null,
"format": "LDLARH <Wt>, [<Xn|SP>{,#0}]"
}
],
"decoder": [
"integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"integer t2 = UInt(Rt2); // ignored by load/store single register",
"integer s = UInt(Rs); // ignored by all loads and store-release",
"",
"AccType acctype = if o0 == '0' then AccType_LIMITEDORDERED else AccType_ORDERED;",
"MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"integer elsize = 8 << UInt(size);",
"integer regsize = if elsize == 64 then 64 else 32;",
"integer datasize = elsize;"
]
}
],
"name": "LDLARH",
"description": [
"Load LOAcquire Register Halfword"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"",
"bits(64) address;",
"bits(datasize) data1;",
"bits(datasize) data2;",
"constant integer dbytes = datasize DIV 8;",
"boolean rt_unknown = FALSE;",
"",
"if memop == MemOp_LOAD && t == t2 then",
" Constraint c = ConstrainUnpredictable(Unpredictable_LDPOVERLAP);",
" assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_UNKNOWN rt_unknown = TRUE; // result is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"if ! postindex then",
" address = address + offset;",
"",
"case memop of",
" when MemOp_STORE",
" data1 = V[t];",
" data2 = V[t2];",
" Mem[address + 0 , dbytes, acctype] = data1;",
" Mem[address + dbytes, dbytes, acctype] = data2;",
"",
" when MemOp_LOAD",
" data1 = Mem[address + 0 , dbytes, acctype];",
" data2 = Mem[address + dbytes, dbytes, acctype];",
" if rt_unknown then",
" data1 = bits(datasize) UNKNOWN;",
" data2 = bits(datasize) UNKNOWN;",
" V[t] = data1;",
" V[t2] = data2;",
"",
"if wback then",
" if postindex then",
" address = address + offset;",
" if n == 31 then",
" SP[] = address;",
" else",
" X[n] = address;"
],
"variants": [
{
"pattern": "opc#2 1 0 1 V#1 0 0 0 L#1 imm7#7 Rt2#5 Rn#5 Rt#5",
"formats": [
{
"condition": "opc == 00",
"format": "LDNP <St1>, <St2>, [<Xn|SP>{, #<imm>}]"
},
{
"condition": "opc == 01",
"format": "LDNP <Dt1>, <Dt2>, [<Xn|SP>{, #<imm>}]"
},
{
"condition": "opc == 10",
"format": "LDNP <Qt1>, <Qt2>, [<Xn|SP>{, #<imm>}]"
}
],
"decoder": [
"boolean wback = FALSE;",
"boolean postindex = FALSE;integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"integer t2 = UInt(Rt2);",
"AccType acctype = AccType_VECSTREAM;",
"MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"if opc == '11' then UnallocatedEncoding();",
"integer scale = 2 + UInt(opc);",
"integer datasize = 8 << scale;",
"bits(64) offset = LSL(SignExtend(imm7, 64), scale);"
]
}
],
"name": "LDNP (SIMD&FP)",
"description": [
"Load Pair of SIMD&FP registers, with Non-temporal hint"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) data1;",
"bits(datasize) data2;",
"constant integer dbytes = datasize DIV 8;",
"boolean rt_unknown = FALSE;",
"",
"if memop == MemOp_LOAD && t == t2 then",
" Constraint c = ConstrainUnpredictable(Unpredictable_LDPOVERLAP);",
" assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_UNKNOWN rt_unknown = TRUE; // result is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"if ! postindex then",
" address = address + offset;",
"",
"case memop of",
" when MemOp_STORE",
" if rt_unknown && t == n then",
" data1 = bits(datasize) UNKNOWN;",
" else",
" data1 = X[t];",
" if rt_unknown && t2 == n then",
" data2 = bits(datasize) UNKNOWN;",
" else",
" data2 = X[t2];",
" Mem[address + 0 , dbytes, acctype] = data1;",
" Mem[address + dbytes, dbytes, acctype] = data2;",
"",
" when MemOp_LOAD",
" data1 = Mem[address + 0 , dbytes, acctype];",
" data2 = Mem[address + dbytes, dbytes, acctype];",
" if rt_unknown then",
" data1 = bits(datasize) UNKNOWN;",
" data2 = bits(datasize) UNKNOWN;",
" X[t] = data1;",
" X[t2] = data2;",
"",
"if wback then",
" if postindex then",
" address = address + offset;",
" if n == 31 then",
" SP[] = address;",
" else",
" X[n] = address;"
],
"variants": [
{
"pattern": "opc#2 1 0 1 V#1 0 0 0 L#1 imm7#7 Rt2#5 Rn#5 Rt#5",
"formats": [
{
"condition": "opc == 00",
"format": "LDNP <Wt1>, <Wt2>, [<Xn|SP>{, #<imm>}]"
},
{
"condition": "opc == 10",
"format": "LDNP <Xt1>, <Xt2>, [<Xn|SP>{, #<imm>}]"
}
],
"decoder": [
"boolean wback = FALSE;",
"boolean postindex = FALSE;integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"integer t2 = UInt(Rt2);",
"AccType acctype = AccType_STREAM;",
"MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"if opc<0> == '1' then UnallocatedEncoding();",
"integer scale = 2 + UInt(opc<1>);",
"integer datasize = 8 << scale;",
"bits(64) offset = LSL(SignExtend(imm7, 64), scale);"
]
}
],
"name": "LDNP",
"description": [
"Load Pair of Registers, with non-temporal hint"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"",
"bits(64) address;",
"bits(datasize) data1;",
"bits(datasize) data2;",
"constant integer dbytes = datasize DIV 8;",
"boolean rt_unknown = FALSE;",
"",
"if memop == MemOp_LOAD && t == t2 then",
" Constraint c = ConstrainUnpredictable(Unpredictable_LDPOVERLAP);",
" assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_UNKNOWN rt_unknown = TRUE; // result is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"if ! postindex then",
" address = address + offset;",
"",
"case memop of",
" when MemOp_STORE",
" data1 = V[t];",
" data2 = V[t2];",
" Mem[address + 0 , dbytes, acctype] = data1;",
" Mem[address + dbytes, dbytes, acctype] = data2;",
"",
" when MemOp_LOAD",
" data1 = Mem[address + 0 , dbytes, acctype];",
" data2 = Mem[address + dbytes, dbytes, acctype];",
" if rt_unknown then",
" data1 = bits(datasize) UNKNOWN;",
" data2 = bits(datasize) UNKNOWN;",
" V[t] = data1;",
" V[t2] = data2;",
"",
"if wback then",
" if postindex then",
" address = address + offset;",
" if n == 31 then",
" SP[] = address;",
" else",
" X[n] = address;"
],
"variants": [
{
"pattern": "opc#2 1 0 1 V#1 0 0 1 L#1 imm7#7 Rt2#5 Rn#5 Rt#5",
"formats": [
{
"condition": "opc == 00",
"format": "LDP <St1>, <St2>, [<Xn|SP>], #<imm>"
},
{
"condition": "opc == 01",
"format": "LDP <Dt1>, <Dt2>, [<Xn|SP>], #<imm>"
},
{
"condition": "opc == 10",
"format": "LDP <Qt1>, <Qt2>, [<Xn|SP>], #<imm>"
}
],
"decoder": [
"boolean wback = TRUE;",
"boolean postindex = TRUE;integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"integer t2 = UInt(Rt2);",
"AccType acctype = AccType_VEC;",
"MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"if opc == '11' then UnallocatedEncoding();",
"integer scale = 2 + UInt(opc);",
"integer datasize = 8 << scale;",
"bits(64) offset = LSL(SignExtend(imm7, 64), scale);"
]
},
{
"pattern": "opc#2 1 0 1 V#1 0 1 1 L#1 imm7#7 Rt2#5 Rn#5 Rt#5",
"formats": [
{
"condition": "opc == 00",
"format": "LDP <St1>, <St2>, [<Xn|SP>, #<imm>]!"
},
{
"condition": "opc == 01",
"format": "LDP <Dt1>, <Dt2>, [<Xn|SP>, #<imm>]!"
},
{
"condition": "opc == 10",
"format": "LDP <Qt1>, <Qt2>, [<Xn|SP>, #<imm>]!"
}
],
"decoder": [
"boolean wback = TRUE;",
"boolean postindex = FALSE;integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"integer t2 = UInt(Rt2);",
"AccType acctype = AccType_VEC;",
"MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"if opc == '11' then UnallocatedEncoding();",
"integer scale = 2 + UInt(opc);",
"integer datasize = 8 << scale;",
"bits(64) offset = LSL(SignExtend(imm7, 64), scale);"
]
},
{
"pattern": "opc#2 1 0 1 V#1 0 1 0 L#1 imm7#7 Rt2#5 Rn#5 Rt#5",
"formats": [
{
"condition": "opc == 00",
"format": "LDP <St1>, <St2>, [<Xn|SP>{, #<imm>}]"
},
{
"condition": "opc == 01",
"format": "LDP <Dt1>, <Dt2>, [<Xn|SP>{, #<imm>}]"
},
{
"condition": "opc == 10",
"format": "LDP <Qt1>, <Qt2>, [<Xn|SP>{, #<imm>}]"
}
],
"decoder": [
"boolean wback = FALSE;",
"boolean postindex = FALSE;integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"integer t2 = UInt(Rt2);",
"AccType acctype = AccType_VEC;",
"MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"if opc == '11' then UnallocatedEncoding();",
"integer scale = 2 + UInt(opc);",
"integer datasize = 8 << scale;",
"bits(64) offset = LSL(SignExtend(imm7, 64), scale);"
]
}
],
"name": "LDP (SIMD&FP)",
"description": [
"Load Pair of SIMD&FP registers"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) data1;",
"bits(datasize) data2;",
"constant integer dbytes = datasize DIV 8;",
"boolean rt_unknown = FALSE;",
"boolean wb_unknown = FALSE;",
"",
"if memop == MemOp_LOAD && wback && (t == n || t2 == n) && n != 31 then",
" Constraint c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD);",
" assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed",
" when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if memop == MemOp_STORE && wback && (t == n || t2 == n) && n != 31 then",
" Constraint c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST);",
" assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_NONE rt_unknown = FALSE; // value stored is pre-writeback",
" when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if memop == MemOp_LOAD && t == t2 then",
" Constraint c = ConstrainUnpredictable(Unpredictable_LDPOVERLAP);",
" assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_UNKNOWN rt_unknown = TRUE; // result is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"if ! postindex then",
" address = address + offset;",
"",
"case memop of",
" when MemOp_STORE",
" if rt_unknown && t == n then",
" data1 = bits(datasize) UNKNOWN;",
" else",
" data1 = X[t];",
" if rt_unknown && t2 == n then",
" data2 = bits(datasize) UNKNOWN;",
" else",
" data2 = X[t2];",
" Mem[address + 0 , dbytes, acctype] = data1;",
" Mem[address + dbytes, dbytes, acctype] = data2;",
"",
" when MemOp_LOAD",
" data1 = Mem[address + 0 , dbytes, acctype];",
" data2 = Mem[address + dbytes, dbytes, acctype];",
" if rt_unknown then",
" data1 = bits(datasize) UNKNOWN;",
" data2 = bits(datasize) UNKNOWN;",
" if signed then",
" X[t] = SignExtend(data1, 64);",
" X[t2] = SignExtend(data2, 64);",
" else",
" X[t] = data1;",
" X[t2] = data2;",
"",
"if wback then",
" if wb_unknown then",
" address = bits(64) UNKNOWN;",
" elsif postindex then",
" address = address + offset;",
" if n == 31 then",
" SP[] = address;",
" else",
" X[n] = address;"
],
"variants": [
{
"pattern": "opc#2 1 0 1 V#1 0 0 1 L#1 imm7#7 Rt2#5 Rn#5 Rt#5",
"formats": [
{
"condition": "opc == 00",
"format": "LDP <Wt1>, <Wt2>, [<Xn|SP>], #<imm>"
},
{
"condition": "opc == 10",
"format": "LDP <Xt1>, <Xt2>, [<Xn|SP>], #<imm>"
}
],
"decoder": [
"boolean wback = TRUE;",
"boolean postindex = TRUE;integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"integer t2 = UInt(Rt2);",
"AccType acctype = AccType_NORMAL;",
"MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"if L:opc<0> == '01' || opc == '11' then UnallocatedEncoding();",
"boolean signed = (opc<0> != '0');",
"integer scale = 2 + UInt(opc<1>);",
"integer datasize = 8 << scale;",
"bits(64) offset = LSL(SignExtend(imm7, 64), scale);"
]
},
{
"pattern": "opc#2 1 0 1 V#1 0 1 1 L#1 imm7#7 Rt2#5 Rn#5 Rt#5",
"formats": [
{
"condition": "opc == 00",
"format": "LDP <Wt1>, <Wt2>, [<Xn|SP>, #<imm>]!"
},
{
"condition": "opc == 10",
"format": "LDP <Xt1>, <Xt2>, [<Xn|SP>, #<imm>]!"
}
],
"decoder": [
"boolean wback = TRUE;",
"boolean postindex = FALSE;integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"integer t2 = UInt(Rt2);",
"AccType acctype = AccType_NORMAL;",
"MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"if L:opc<0> == '01' || opc == '11' then UnallocatedEncoding();",
"boolean signed = (opc<0> != '0');",
"integer scale = 2 + UInt(opc<1>);",
"integer datasize = 8 << scale;",
"bits(64) offset = LSL(SignExtend(imm7, 64), scale);"
]
},
{
"pattern": "opc#2 1 0 1 V#1 0 1 0 L#1 imm7#7 Rt2#5 Rn#5 Rt#5",
"formats": [
{
"condition": "opc == 00",
"format": "LDP <Wt1>, <Wt2>, [<Xn|SP>{, #<imm>}]"
},
{
"condition": "opc == 10",
"format": "LDP <Xt1>, <Xt2>, [<Xn|SP>{, #<imm>}]"
}
],
"decoder": [
"boolean wback = FALSE;",
"boolean postindex = FALSE;integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"integer t2 = UInt(Rt2);",
"AccType acctype = AccType_NORMAL;",
"MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"if L:opc<0> == '01' || opc == '11' then UnallocatedEncoding();",
"boolean signed = (opc<0> != '0');",
"integer scale = 2 + UInt(opc<1>);",
"integer datasize = 8 << scale;",
"bits(64) offset = LSL(SignExtend(imm7, 64), scale);"
]
}
],
"name": "LDP",
"description": [
"Load Pair of Registers"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) data1;",
"bits(datasize) data2;",
"constant integer dbytes = datasize DIV 8;",
"boolean rt_unknown = FALSE;",
"boolean wb_unknown = FALSE;",
"",
"if memop == MemOp_LOAD && wback && (t == n || t2 == n) && n != 31 then",
" Constraint c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD);",
" assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed",
" when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if memop == MemOp_STORE && wback && (t == n || t2 == n) && n != 31 then",
" Constraint c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST);",
" assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_NONE rt_unknown = FALSE; // value stored is pre-writeback",
" when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if memop == MemOp_LOAD && t == t2 then",
" Constraint c = ConstrainUnpredictable(Unpredictable_LDPOVERLAP);",
" assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_UNKNOWN rt_unknown = TRUE; // result is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"if ! postindex then",
" address = address + offset;",
"",
"case memop of",
" when MemOp_STORE",
" if rt_unknown && t == n then",
" data1 = bits(datasize) UNKNOWN;",
" else",
" data1 = X[t];",
" if rt_unknown && t2 == n then",
" data2 = bits(datasize) UNKNOWN;",
" else",
" data2 = X[t2];",
" Mem[address + 0 , dbytes, acctype] = data1;",
" Mem[address + dbytes, dbytes, acctype] = data2;",
"",
" when MemOp_LOAD",
" data1 = Mem[address + 0 , dbytes, acctype];",
" data2 = Mem[address + dbytes, dbytes, acctype];",
" if rt_unknown then",
" data1 = bits(datasize) UNKNOWN;",
" data2 = bits(datasize) UNKNOWN;",
" if signed then",
" X[t] = SignExtend(data1, 64);",
" X[t2] = SignExtend(data2, 64);",
" else",
" X[t] = data1;",
" X[t2] = data2;",
"",
"if wback then",
" if wb_unknown then",
" address = bits(64) UNKNOWN;",
" elsif postindex then",
" address = address + offset;",
" if n == 31 then",
" SP[] = address;",
" else",
" X[n] = address;"
],
"variants": [
{
"pattern": "opc#2 1 0 1 V#1 0 0 1 L#1 imm7#7 Rt2#5 Rn#5 Rt#5",
"formats": [
{
"condition": null,
"format": "LDPSW <Xt1>, <Xt2>, [<Xn|SP>], #<imm>"
}
],
"decoder": [
"boolean wback = TRUE;",
"boolean postindex = TRUE;integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"integer t2 = UInt(Rt2);",
"AccType acctype = AccType_NORMAL;",
"MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"if L:opc<0> == '01' || opc == '11' then UnallocatedEncoding();",
"boolean signed = (opc<0> != '0');",
"integer scale = 2 + UInt(opc<1>);",
"integer datasize = 8 << scale;",
"bits(64) offset = LSL(SignExtend(imm7, 64), scale);"
]
},
{
"pattern": "opc#2 1 0 1 V#1 0 1 1 L#1 imm7#7 Rt2#5 Rn#5 Rt#5",
"formats": [
{
"condition": null,
"format": "LDPSW <Xt1>, <Xt2>, [<Xn|SP>, #<imm>]!"
}
],
"decoder": [
"boolean wback = TRUE;",
"boolean postindex = FALSE;integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"integer t2 = UInt(Rt2);",
"AccType acctype = AccType_NORMAL;",
"MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"if L:opc<0> == '01' || opc == '11' then UnallocatedEncoding();",
"boolean signed = (opc<0> != '0');",
"integer scale = 2 + UInt(opc<1>);",
"integer datasize = 8 << scale;",
"bits(64) offset = LSL(SignExtend(imm7, 64), scale);"
]
},
{
"pattern": "opc#2 1 0 1 V#1 0 1 0 L#1 imm7#7 Rt2#5 Rn#5 Rt#5",
"formats": [
{
"condition": null,
"format": "LDPSW <Xt1>, <Xt2>, [<Xn|SP>{, #<imm>}]"
}
],
"decoder": [
"boolean wback = FALSE;",
"boolean postindex = FALSE;integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"integer t2 = UInt(Rt2);",
"AccType acctype = AccType_NORMAL;",
"MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"if L:opc<0> == '01' || opc == '11' then UnallocatedEncoding();",
"boolean signed = (opc<0> != '0');",
"integer scale = 2 + UInt(opc<1>);",
"integer datasize = 8 << scale;",
"bits(64) offset = LSL(SignExtend(imm7, 64), scale);"
]
}
],
"name": "LDPSW",
"description": [
"Load Pair of Registers Signed Word"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"",
"bits(64) address;",
"bits(datasize) data;",
"",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"if ! postindex then",
" address = address + offset;",
"",
"case memop of",
" when MemOp_STORE",
" data = V[t];",
" Mem[address, datasize DIV 8, acctype] = data;",
"",
" when MemOp_LOAD",
" data = Mem[address, datasize DIV 8, acctype];",
" V[t] = data;",
"",
"if wback then",
" if postindex then",
" address = address + offset;",
" if n == 31 then",
" SP[] = address;",
" else",
" X[n] = address;"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 opc#2 0 imm9#9 0 1 Rn#5 Rt#5",
"formats": [
{
"condition": "size == 00 && opc == 01",
"format": "LDR <Bt>, [<Xn|SP>], #<simm>"
},
{
"condition": "size == 01 && opc == 01",
"format": "LDR <Ht>, [<Xn|SP>], #<simm>"
},
{
"condition": "size == 10 && opc == 01",
"format": "LDR <St>, [<Xn|SP>], #<simm>"
},
{
"condition": "size == 11 && opc == 01",
"format": "LDR <Dt>, [<Xn|SP>], #<simm>"
},
{
"condition": "size == 00 && opc == 11",
"format": "LDR <Qt>, [<Xn|SP>], #<simm>"
}
],
"decoder": [
"boolean wback = TRUE;",
"boolean postindex = TRUE;",
"integer scale = UInt(opc<1>:size);",
"if scale > 4 then UnallocatedEncoding();",
"bits(64) offset = SignExtend(imm9, 64);integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"AccType acctype = AccType_VEC;",
"MemOp memop = if opc<0> == '1' then MemOp_LOAD else MemOp_STORE;",
"integer datasize = 8 << scale;"
]
},
{
"pattern": "size#2 1 1 1 V#1 0 0 opc#2 0 imm9#9 1 1 Rn#5 Rt#5",
"formats": [
{
"condition": "size == 00 && opc == 01",
"format": "LDR <Bt>, [<Xn|SP>, #<simm>]!"
},
{
"condition": "size == 01 && opc == 01",
"format": "LDR <Ht>, [<Xn|SP>, #<simm>]!"
},
{
"condition": "size == 10 && opc == 01",
"format": "LDR <St>, [<Xn|SP>, #<simm>]!"
},
{
"condition": "size == 11 && opc == 01",
"format": "LDR <Dt>, [<Xn|SP>, #<simm>]!"
},
{
"condition": "size == 00 && opc == 11",
"format": "LDR <Qt>, [<Xn|SP>, #<simm>]!"
}
],
"decoder": [
"boolean wback = TRUE;",
"boolean postindex = FALSE;",
"integer scale = UInt(opc<1>:size);",
"if scale > 4 then UnallocatedEncoding();",
"bits(64) offset = SignExtend(imm9, 64);integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"AccType acctype = AccType_VEC;",
"MemOp memop = if opc<0> == '1' then MemOp_LOAD else MemOp_STORE;",
"integer datasize = 8 << scale;"
]
},
{
"pattern": "size#2 1 1 1 V#1 0 1 opc#2 imm12#12 Rn#5 Rt#5",
"formats": [
{
"condition": "size == 00 && opc == 01",
"format": "LDR <Bt>, [<Xn|SP>{, #<pimm>}]"
},
{
"condition": "size == 01 && opc == 01",
"format": "LDR <Ht>, [<Xn|SP>{, #<pimm>}]"
},
{
"condition": "size == 10 && opc == 01",
"format": "LDR <St>, [<Xn|SP>{, #<pimm>}]"
},
{
"condition": "size == 11 && opc == 01",
"format": "LDR <Dt>, [<Xn|SP>{, #<pimm>}]"
},
{
"condition": "size == 00 && opc == 11",
"format": "LDR <Qt>, [<Xn|SP>{, #<pimm>}]"
}
],
"decoder": [
"boolean wback = FALSE;",
"boolean postindex = FALSE;",
"integer scale = UInt(opc<1>:size);",
"if scale > 4 then UnallocatedEncoding();",
"bits(64) offset = LSL(ZeroExtend(imm12, 64), scale);integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"AccType acctype = AccType_VEC;",
"MemOp memop = if opc<0> == '1' then MemOp_LOAD else MemOp_STORE;",
"integer datasize = 8 << scale;"
]
}
],
"name": "LDR (immediate, SIMD&FP)",
"description": [
"Load SIMD&FP Register (immediate offset)"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) data;",
"boolean wb_unknown = FALSE;",
"boolean rt_unknown = FALSE;",
"",
"if memop == MemOp_LOAD && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD);",
" assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed",
" when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if memop == MemOp_STORE && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST);",
" assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_NONE rt_unknown = FALSE; // value stored is original value",
" when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if n == 31 then",
" if memop != MemOp_PREFETCH then CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"if ! postindex then",
" address = address + offset;",
"",
"case memop of",
" when MemOp_STORE",
" if rt_unknown then",
" data = bits(datasize) UNKNOWN;",
" else",
" data = X[t];",
" Mem[address, datasize DIV 8, acctype] = data;",
"",
" when MemOp_LOAD",
" data = Mem[address, datasize DIV 8, acctype];",
" if signed then",
" X[t] = SignExtend(data, regsize);",
" else",
" X[t] = ZeroExtend(data, regsize);",
"",
" when MemOp_PREFETCH",
" Prefetch(address, t<4:0>);",
"",
"if wback then",
" if wb_unknown then",
" address = bits(64) UNKNOWN;",
" elsif postindex then",
" address = address + offset;",
" if n == 31 then",
" SP[] = address;",
" else",
" X[n] = address;"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 opc#2 0 imm9#9 0 1 Rn#5 Rt#5",
"formats": [
{
"condition": "size == 10",
"format": "LDR <Wt>, [<Xn|SP>], #<simm>"
},
{
"condition": "size == 11",
"format": "LDR <Xt>, [<Xn|SP>], #<simm>"
}
],
"decoder": [
"boolean wback = TRUE;",
"boolean postindex = TRUE;",
"integer scale = UInt(size);",
"bits(64) offset = SignExtend(imm9, 64);integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"AccType acctype = AccType_NORMAL;",
"MemOp memop;",
"boolean signed;",
"integer regsize;",
"",
"if opc<1> == '0' then",
" // store or zero-extending load",
" memop = if opc<0> == '1' then MemOp_LOAD else MemOp_STORE;",
" regsize = if size == '11' then 64 else 32;",
" signed = FALSE;",
"else",
" if size == '11' then",
" UnallocatedEncoding();",
" else",
" // sign-extending load",
" memop = MemOp_LOAD;",
" if size == '10' && opc<0> == '1' then UnallocatedEncoding();",
" regsize = if opc<0> == '1' then 32 else 64;",
" signed = TRUE;",
"",
"integer datasize = 8 << scale;"
]
},
{
"pattern": "size#2 1 1 1 V#1 0 0 opc#2 0 imm9#9 1 1 Rn#5 Rt#5",
"formats": [
{
"condition": "size == 10",
"format": "LDR <Wt>, [<Xn|SP>, #<simm>]!"
},
{
"condition": "size == 11",
"format": "LDR <Xt>, [<Xn|SP>, #<simm>]!"
}
],
"decoder": [
"boolean wback = TRUE;",
"boolean postindex = FALSE;",
"integer scale = UInt(size);",
"bits(64) offset = SignExtend(imm9, 64);integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"AccType acctype = AccType_NORMAL;",
"MemOp memop;",
"boolean signed;",
"integer regsize;",
"",
"if opc<1> == '0' then",
" // store or zero-extending load",
" memop = if opc<0> == '1' then MemOp_LOAD else MemOp_STORE;",
" regsize = if size == '11' then 64 else 32;",
" signed = FALSE;",
"else",
" if size == '11' then",
" UnallocatedEncoding();",
" else",
" // sign-extending load",
" memop = MemOp_LOAD;",
" if size == '10' && opc<0> == '1' then UnallocatedEncoding();",
" regsize = if opc<0> == '1' then 32 else 64;",
" signed = TRUE;",
"",
"integer datasize = 8 << scale;"
]
},
{
"pattern": "size#2 1 1 1 V#1 0 1 opc#2 imm12#12 Rn#5 Rt#5",
"formats": [
{
"condition": "size == 10",
"format": "LDR <Wt>, [<Xn|SP>{, #<pimm>}]"
},
{
"condition": "size == 11",
"format": "LDR <Xt>, [<Xn|SP>{, #<pimm>}]"
}
],
"decoder": [
"boolean wback = FALSE;",
"boolean postindex = FALSE;",
"integer scale = UInt(size);",
"bits(64) offset = LSL(ZeroExtend(imm12, 64), scale);integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"AccType acctype = AccType_NORMAL;",
"MemOp memop;",
"boolean signed;",
"integer regsize;",
"",
"if opc<1> == '0' then",
" // store or zero-extending load",
" memop = if opc<0> == '1' then MemOp_LOAD else MemOp_STORE;",
" regsize = if size == '11' then 64 else 32;",
" signed = FALSE;",
"else",
" if size == '11' then",
" UnallocatedEncoding();",
" else",
" // sign-extending load",
" memop = MemOp_LOAD;",
" if size == '10' && opc<0> == '1' then UnallocatedEncoding();",
" regsize = if opc<0> == '1' then 32 else 64;",
" signed = TRUE;",
"",
"integer datasize = 8 << scale;"
]
}
],
"name": "LDR (immediate)",
"description": [
"Load Register (immediate)"
]
}
{
"operation": [
"bits(64) address = PC[] + offset;",
"bits(size*8) data;",
"",
"CheckFPAdvSIMDEnabled64();",
"",
"data = Mem[address, size, AccType_VEC];",
"V[t] = data;"
],
"variants": [
{
"pattern": "opc#2 0 1 1 V#1 0 0 imm19#19 Rt#5",
"formats": [
{
"condition": "opc == 00",
"format": "LDR <St>, <label>"
},
{
"condition": "opc == 01",
"format": "LDR <Dt>, <label>"
},
{
"condition": "opc == 10",
"format": "LDR <Qt>, <label>"
}
],
"decoder": [
"integer t = UInt(Rt);",
"integer size;",
"bits(64) offset;",
"",
"case opc of",
" when '00'",
" size = 4;",
" when '01'",
" size = 8;",
" when '10'",
" size = 16;",
" when '11'",
" UnallocatedEncoding();",
"",
"offset = SignExtend(imm19:'00', 64);"
]
}
],
"name": "LDR (literal, SIMD&FP)",
"description": [
"Load SIMD&FP Register (PC-relative literal)"
]
}
{
"operation": [
"bits(64) address = PC[] + offset;",
"bits(size*8) data;",
"",
"case memop of",
" when MemOp_LOAD",
" data = Mem[address, size, AccType_NORMAL];",
" if signed then",
" X[t] = SignExtend(data, 64);",
" else",
" X[t] = data;",
"",
" when MemOp_PREFETCH",
" Prefetch(address, t<4:0>);"
],
"variants": [
{
"pattern": "opc#2 0 1 1 V#1 0 0 imm19#19 Rt#5",
"formats": [
{
"condition": "opc == 00",
"format": "LDR <Wt>, <label>"
},
{
"condition": "opc == 01",
"format": "LDR <Xt>, <label>"
}
],
"decoder": [
"integer t = UInt(Rt);",
"MemOp memop = MemOp_LOAD;",
"boolean signed = FALSE;",
"integer size;",
"bits(64) offset;",
"",
"case opc of",
" when '00'",
" size = 4;",
" when '01'",
" size = 8;",
" when '10'",
" size = 4;",
" signed = TRUE;",
" when '11'",
" memop = MemOp_PREFETCH;",
"",
"offset = SignExtend(imm19:'00', 64);"
]
}
],
"name": "LDR (literal)",
"description": [
"Load Register (literal)"
]
}
{
"operation": [
"bits(64) offset = ExtendReg(m, extend_type, shift);",
"CheckFPAdvSIMDEnabled64();",
"",
"bits(64) address;",
"bits(datasize) data;",
"",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"if ! postindex then",
" address = address + offset;",
"",
"case memop of",
" when MemOp_STORE",
" data = V[t];",
" Mem[address, datasize DIV 8, acctype] = data;",
"",
" when MemOp_LOAD",
" data = Mem[address, datasize DIV 8, acctype];",
" V[t] = data;",
"",
"if wback then",
" if postindex then",
" address = address + offset;",
" if n == 31 then",
" SP[] = address;",
" else",
" X[n] = address;"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 opc#2 1 Rm#5 option#3 S#1 1 0 Rn#5 Rt#5",
"formats": [
{
"condition": "size == 00 && opc == 01 && option != 011",
"format": "LDR <Bt>, [<Xn|SP>, (<Wm>|<Xm>), <extend> {<amount>}]"
},
{
"condition": "size == 00 && opc == 01 && option == 011",
"format": "LDR <Bt>, [<Xn|SP>, <Xm>{, LSL <amount>}]"
},
{
"condition": "size == 01 && opc == 01",
"format": "LDR <Ht>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]"
},
{
"condition": "size == 10 && opc == 01",
"format": "LDR <St>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]"
},
{
"condition": "size == 11 && opc == 01",
"format": "LDR <Dt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]"
},
{
"condition": "size == 00 && opc == 11",
"format": "LDR <Qt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]"
}
],
"decoder": [
"boolean wback = FALSE;",
"boolean postindex = FALSE;",
"integer scale = UInt(opc<1>:size);",
"if scale > 4 then UnallocatedEncoding();",
"if option<1> == '0' then UnallocatedEncoding(); // sub-word index",
"ExtendType extend_type = DecodeRegExtend(option);",
"integer shift = if S == '1' then scale else 0;integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"integer m = UInt(Rm);",
"AccType acctype = AccType_VEC;",
"MemOp memop = if opc<0> == '1' then MemOp_LOAD else MemOp_STORE;",
"integer datasize = 8 << scale;"
]
}
],
"name": "LDR (register, SIMD&FP)",
"description": [
"Load SIMD&FP Register (register offset)"
]
}
{
"operation": [
"bits(64) offset = ExtendReg(m, extend_type, shift);",
"bits(64) address;",
"bits(datasize) data;",
"boolean wb_unknown = FALSE;",
"boolean rt_unknown = FALSE;",
"",
"if memop == MemOp_LOAD && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD);",
" assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed",
" when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if memop == MemOp_STORE && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST);",
" assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_NONE rt_unknown = FALSE; // value stored is original value",
" when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if n == 31 then",
" if memop != MemOp_PREFETCH then CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"if ! postindex then",
" address = address + offset;",
"",
"case memop of",
" when MemOp_STORE",
" if rt_unknown then",
" data = bits(datasize) UNKNOWN;",
" else",
" data = X[t];",
" Mem[address, datasize DIV 8, acctype] = data;",
"",
" when MemOp_LOAD",
" data = Mem[address, datasize DIV 8, acctype];",
" if signed then",
" X[t] = SignExtend(data, regsize);",
" else",
" X[t] = ZeroExtend(data, regsize);",
"",
" when MemOp_PREFETCH",
" Prefetch(address, t<4:0>);",
"",
"if wback then",
" if wb_unknown then",
" address = bits(64) UNKNOWN;",
" elsif postindex then",
" address = address + offset;",
" if n == 31 then",
" SP[] = address;",
" else",
" X[n] = address;"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 opc#2 1 Rm#5 option#3 S#1 1 0 Rn#5 Rt#5",
"formats": [
{
"condition": "size == 10",
"format": "LDR <Wt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]"
},
{
"condition": "size == 11",
"format": "LDR <Xt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]"
}
],
"decoder": [
"boolean wback = FALSE;",
"boolean postindex = FALSE;",
"integer scale = UInt(size);",
"if option<1> == '0' then UnallocatedEncoding(); // sub-word index",
"ExtendType extend_type = DecodeRegExtend(option);",
"integer shift = if S == '1' then scale else 0;integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"integer m = UInt(Rm);",
"AccType acctype = AccType_NORMAL;",
"MemOp memop;",
"boolean signed;",
"integer regsize;",
"",
"if opc<1> == '0' then",
" // store or zero-extending load",
" memop = if opc<0> == '1' then MemOp_LOAD else MemOp_STORE;",
" regsize = if size == '11' then 64 else 32;",
" signed = FALSE;",
"else",
" if size == '11' then",
" memop = MemOp_PREFETCH;",
" if opc<0> == '1' then UnallocatedEncoding();",
" else",
" // sign-extending load",
" memop = MemOp_LOAD;",
" if size == '10' && opc<0> == '1' then UnallocatedEncoding();",
" regsize = if opc<0> == '1' then 32 else 64;",
" signed = TRUE;",
"",
"integer datasize = 8 << scale;"
]
}
],
"name": "LDR (register)",
"description": [
"Load Register (register)"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) data;",
"boolean wb_unknown = FALSE;",
"boolean rt_unknown = FALSE;",
"",
"if memop == MemOp_LOAD && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD);",
" assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed",
" when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if memop == MemOp_STORE && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST);",
" assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_NONE rt_unknown = FALSE; // value stored is original value",
" when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if n == 31 then",
" if memop != MemOp_PREFETCH then CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"if ! postindex then",
" address = address + offset;",
"",
"case memop of",
" when MemOp_STORE",
" if rt_unknown then",
" data = bits(datasize) UNKNOWN;",
" else",
" data = X[t];",
" Mem[address, datasize DIV 8, acctype] = data;",
"",
" when MemOp_LOAD",
" data = Mem[address, datasize DIV 8, acctype];",
" if signed then",
" X[t] = SignExtend(data, regsize);",
" else",
" X[t] = ZeroExtend(data, regsize);",
"",
" when MemOp_PREFETCH",
" Prefetch(address, t<4:0>);",
"",
"if wback then",
" if wb_unknown then",
" address = bits(64) UNKNOWN;",
" elsif postindex then",
" address = address + offset;",
" if n == 31 then",
" SP[] = address;",
" else",
" X[n] = address;"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 opc#2 0 imm9#9 0 1 Rn#5 Rt#5",
"formats": [
{
"condition": null,
"format": "LDRB <Wt>, [<Xn|SP>], #<simm>"
}
],
"decoder": [
"boolean wback = TRUE;",
"boolean postindex = TRUE;",
"integer scale = UInt(size);",
"bits(64) offset = SignExtend(imm9, 64);integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"AccType acctype = AccType_NORMAL;",
"MemOp memop;",
"boolean signed;",
"integer regsize;",
"",
"if opc<1> == '0' then",
" // store or zero-extending load",
" memop = if opc<0> == '1' then MemOp_LOAD else MemOp_STORE;",
" regsize = if size == '11' then 64 else 32;",
" signed = FALSE;",
"else",
" if size == '11' then",
" UnallocatedEncoding();",
" else",
" // sign-extending load",
" memop = MemOp_LOAD;",
" if size == '10' && opc<0> == '1' then UnallocatedEncoding();",
" regsize = if opc<0> == '1' then 32 else 64;",
" signed = TRUE;",
"",
"integer datasize = 8 << scale;"
]
},
{
"pattern": "size#2 1 1 1 V#1 0 0 opc#2 0 imm9#9 1 1 Rn#5 Rt#5",
"formats": [
{
"condition": null,
"format": "LDRB <Wt>, [<Xn|SP>, #<simm>]!"
}
],
"decoder": [
"boolean wback = TRUE;",
"boolean postindex = FALSE;",
"integer scale = UInt(size);",
"bits(64) offset = SignExtend(imm9, 64);integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"AccType acctype = AccType_NORMAL;",
"MemOp memop;",
"boolean signed;",
"integer regsize;",
"",
"if opc<1> == '0' then",
" // store or zero-extending load",
" memop = if opc<0> == '1' then MemOp_LOAD else MemOp_STORE;",
" regsize = if size == '11' then 64 else 32;",
" signed = FALSE;",
"else",
" if size == '11' then",
" UnallocatedEncoding();",
" else",
" // sign-extending load",
" memop = MemOp_LOAD;",
" if size == '10' && opc<0> == '1' then UnallocatedEncoding();",
" regsize = if opc<0> == '1' then 32 else 64;",
" signed = TRUE;",
"",
"integer datasize = 8 << scale;"
]
},
{
"pattern": "size#2 1 1 1 V#1 0 1 opc#2 imm12#12 Rn#5 Rt#5",
"formats": [
{
"condition": null,
"format": "LDRB <Wt>, [<Xn|SP>{, #<pimm>}]"
}
],
"decoder": [
"boolean wback = FALSE;",
"boolean postindex = FALSE;",
"integer scale = UInt(size);",
"bits(64) offset = LSL(ZeroExtend(imm12, 64), scale);integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"AccType acctype = AccType_NORMAL;",
"MemOp memop;",
"boolean signed;",
"integer regsize;",
"",
"if opc<1> == '0' then",
" // store or zero-extending load",
" memop = if opc<0> == '1' then MemOp_LOAD else MemOp_STORE;",
" regsize = if size == '11' then 64 else 32;",
" signed = FALSE;",
"else",
" if size == '11' then",
" UnallocatedEncoding();",
" else",
" // sign-extending load",
" memop = MemOp_LOAD;",
" if size == '10' && opc<0> == '1' then UnallocatedEncoding();",
" regsize = if opc<0> == '1' then 32 else 64;",
" signed = TRUE;",
"",
"integer datasize = 8 << scale;"
]
}
],
"name": "LDRB (immediate)",
"description": [
"Load Register Byte (immediate)"
]
}
{
"operation": [
"bits(64) offset = ExtendReg(m, extend_type, shift);",
"bits(64) address;",
"bits(datasize) data;",
"boolean wb_unknown = FALSE;",
"boolean rt_unknown = FALSE;",
"",
"if memop == MemOp_LOAD && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD);",
" assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed",
" when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if memop == MemOp_STORE && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST);",
" assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_NONE rt_unknown = FALSE; // value stored is original value",
" when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if n == 31 then",
" if memop != MemOp_PREFETCH then CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"if ! postindex then",
" address = address + offset;",
"",
"case memop of",
" when MemOp_STORE",
" if rt_unknown then",
" data = bits(datasize) UNKNOWN;",
" else",
" data = X[t];",
" Mem[address, datasize DIV 8, acctype] = data;",
"",
" when MemOp_LOAD",
" data = Mem[address, datasize DIV 8, acctype];",
" if signed then",
" X[t] = SignExtend(data, regsize);",
" else",
" X[t] = ZeroExtend(data, regsize);",
"",
" when MemOp_PREFETCH",
" Prefetch(address, t<4:0>);",
"",
"if wback then",
" if wb_unknown then",
" address = bits(64) UNKNOWN;",
" elsif postindex then",
" address = address + offset;",
" if n == 31 then",
" SP[] = address;",
" else",
" X[n] = address;"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 opc#2 1 Rm#5 option#3 S#1 1 0 Rn#5 Rt#5",
"formats": [
{
"condition": "option != 011",
"format": "LDRB <Wt>, [<Xn|SP>, (<Wm>|<Xm>), <extend> {<amount>}]"
},
{
"condition": "option == 011",
"format": "LDRB <Wt>, [<Xn|SP>, <Xm>{, LSL <amount>}]"
}
],
"decoder": [
"boolean wback = FALSE;",
"boolean postindex = FALSE;",
"integer scale = UInt(size);",
"if option<1> == '0' then UnallocatedEncoding(); // sub-word index",
"ExtendType extend_type = DecodeRegExtend(option);",
"integer shift = if S == '1' then scale else 0;integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"integer m = UInt(Rm);",
"AccType acctype = AccType_NORMAL;",
"MemOp memop;",
"boolean signed;",
"integer regsize;",
"",
"if opc<1> == '0' then",
" // store or zero-extending load",
" memop = if opc<0> == '1' then MemOp_LOAD else MemOp_STORE;",
" regsize = if size == '11' then 64 else 32;",
" signed = FALSE;",
"else",
" if size == '11' then",
" memop = MemOp_PREFETCH;",
" if opc<0> == '1' then UnallocatedEncoding();",
" else",
" // sign-extending load",
" memop = MemOp_LOAD;",
" if size == '10' && opc<0> == '1' then UnallocatedEncoding();",
" regsize = if opc<0> == '1' then 32 else 64;",
" signed = TRUE;",
"",
"integer datasize = 8 << scale;"
]
}
],
"name": "LDRB (register)",
"description": [
"Load Register Byte (register)"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) data;",
"boolean wb_unknown = FALSE;",
"boolean rt_unknown = FALSE;",
"",
"if memop == MemOp_LOAD && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD);",
" assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed",
" when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if memop == MemOp_STORE && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST);",
" assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_NONE rt_unknown = FALSE; // value stored is original value",
" when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if n == 31 then",
" if memop != MemOp_PREFETCH then CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"if ! postindex then",
" address = address + offset;",
"",
"case memop of",
" when MemOp_STORE",
" if rt_unknown then",
" data = bits(datasize) UNKNOWN;",
" else",
" data = X[t];",
" Mem[address, datasize DIV 8, acctype] = data;",
"",
" when MemOp_LOAD",
" data = Mem[address, datasize DIV 8, acctype];",
" if signed then",
" X[t] = SignExtend(data, regsize);",
" else",
" X[t] = ZeroExtend(data, regsize);",
"",
" when MemOp_PREFETCH",
" Prefetch(address, t<4:0>);",
"",
"if wback then",
" if wb_unknown then",
" address = bits(64) UNKNOWN;",
" elsif postindex then",
" address = address + offset;",
" if n == 31 then",
" SP[] = address;",
" else",
" X[n] = address;"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 opc#2 0 imm9#9 0 1 Rn#5 Rt#5",
"formats": [
{
"condition": null,
"format": "LDRH <Wt>, [<Xn|SP>], #<simm>"
}
],
"decoder": [
"boolean wback = TRUE;",
"boolean postindex = TRUE;",
"integer scale = UInt(size);",
"bits(64) offset = SignExtend(imm9, 64);integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"AccType acctype = AccType_NORMAL;",
"MemOp memop;",
"boolean signed;",
"integer regsize;",
"",
"if opc<1> == '0' then",
" // store or zero-extending load",
" memop = if opc<0> == '1' then MemOp_LOAD else MemOp_STORE;",
" regsize = if size == '11' then 64 else 32;",
" signed = FALSE;",
"else",
" if size == '11' then",
" UnallocatedEncoding();",
" else",
" // sign-extending load",
" memop = MemOp_LOAD;",
" if size == '10' && opc<0> == '1' then UnallocatedEncoding();",
" regsize = if opc<0> == '1' then 32 else 64;",
" signed = TRUE;",
"",
"integer datasize = 8 << scale;"
]
},
{
"pattern": "size#2 1 1 1 V#1 0 0 opc#2 0 imm9#9 1 1 Rn#5 Rt#5",
"formats": [
{
"condition": null,
"format": "LDRH <Wt>, [<Xn|SP>, #<simm>]!"
}
],
"decoder": [
"boolean wback = TRUE;",
"boolean postindex = FALSE;",
"integer scale = UInt(size);",
"bits(64) offset = SignExtend(imm9, 64);integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"AccType acctype = AccType_NORMAL;",
"MemOp memop;",
"boolean signed;",
"integer regsize;",
"",
"if opc<1> == '0' then",
" // store or zero-extending load",
" memop = if opc<0> == '1' then MemOp_LOAD else MemOp_STORE;",
" regsize = if size == '11' then 64 else 32;",
" signed = FALSE;",
"else",
" if size == '11' then",
" UnallocatedEncoding();",
" else",
" // sign-extending load",
" memop = MemOp_LOAD;",
" if size == '10' && opc<0> == '1' then UnallocatedEncoding();",
" regsize = if opc<0> == '1' then 32 else 64;",
" signed = TRUE;",
"",
"integer datasize = 8 << scale;"
]
},
{
"pattern": "size#2 1 1 1 V#1 0 1 opc#2 imm12#12 Rn#5 Rt#5",
"formats": [
{
"condition": null,
"format": "LDRH <Wt>, [<Xn|SP>{, #<pimm>}]"
}
],
"decoder": [
"boolean wback = FALSE;",
"boolean postindex = FALSE;",
"integer scale = UInt(size);",
"bits(64) offset = LSL(ZeroExtend(imm12, 64), scale);integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"AccType acctype = AccType_NORMAL;",
"MemOp memop;",
"boolean signed;",
"integer regsize;",
"",
"if opc<1> == '0' then",
" // store or zero-extending load",
" memop = if opc<0> == '1' then MemOp_LOAD else MemOp_STORE;",
" regsize = if size == '11' then 64 else 32;",
" signed = FALSE;",
"else",
" if size == '11' then",
" UnallocatedEncoding();",
" else",
" // sign-extending load",
" memop = MemOp_LOAD;",
" if size == '10' && opc<0> == '1' then UnallocatedEncoding();",
" regsize = if opc<0> == '1' then 32 else 64;",
" signed = TRUE;",
"",
"integer datasize = 8 << scale;"
]
}
],
"name": "LDRH (immediate)",
"description": [
"Load Register Halfword (immediate)"
]
}
{
"operation": [
"bits(64) offset = ExtendReg(m, extend_type, shift);",
"bits(64) address;",
"bits(datasize) data;",
"boolean wb_unknown = FALSE;",
"boolean rt_unknown = FALSE;",
"",
"if memop == MemOp_LOAD && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD);",
" assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed",
" when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if memop == MemOp_STORE && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST);",
" assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_NONE rt_unknown = FALSE; // value stored is original value",
" when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if n == 31 then",
" if memop != MemOp_PREFETCH then CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"if ! postindex then",
" address = address + offset;",
"",
"case memop of",
" when MemOp_STORE",
" if rt_unknown then",
" data = bits(datasize) UNKNOWN;",
" else",
" data = X[t];",
" Mem[address, datasize DIV 8, acctype] = data;",
"",
" when MemOp_LOAD",
" data = Mem[address, datasize DIV 8, acctype];",
" if signed then",
" X[t] = SignExtend(data, regsize);",
" else",
" X[t] = ZeroExtend(data, regsize);",
"",
" when MemOp_PREFETCH",
" Prefetch(address, t<4:0>);",
"",
"if wback then",
" if wb_unknown then",
" address = bits(64) UNKNOWN;",
" elsif postindex then",
" address = address + offset;",
" if n == 31 then",
" SP[] = address;",
" else",
" X[n] = address;"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 opc#2 1 Rm#5 option#3 S#1 1 0 Rn#5 Rt#5",
"formats": [
{
"condition": null,
"format": "LDRH <Wt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]"
}
],
"decoder": [
"boolean wback = FALSE;",
"boolean postindex = FALSE;",
"integer scale = UInt(size);",
"if option<1> == '0' then UnallocatedEncoding(); // sub-word index",
"ExtendType extend_type = DecodeRegExtend(option);",
"integer shift = if S == '1' then scale else 0;integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"integer m = UInt(Rm);",
"AccType acctype = AccType_NORMAL;",
"MemOp memop;",
"boolean signed;",
"integer regsize;",
"",
"if opc<1> == '0' then",
" // store or zero-extending load",
" memop = if opc<0> == '1' then MemOp_LOAD else MemOp_STORE;",
" regsize = if size == '11' then 64 else 32;",
" signed = FALSE;",
"else",
" if size == '11' then",
" memop = MemOp_PREFETCH;",
" if opc<0> == '1' then UnallocatedEncoding();",
" else",
" // sign-extending load",
" memop = MemOp_LOAD;",
" if size == '10' && opc<0> == '1' then UnallocatedEncoding();",
" regsize = if opc<0> == '1' then 32 else 64;",
" signed = TRUE;",
"",
"integer datasize = 8 << scale;"
]
}
],
"name": "LDRH (register)",
"description": [
"Load Register Halfword (register)"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) data;",
"boolean wb_unknown = FALSE;",
"boolean rt_unknown = FALSE;",
"",
"if memop == MemOp_LOAD && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD);",
" assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed",
" when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if memop == MemOp_STORE && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST);",
" assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_NONE rt_unknown = FALSE; // value stored is original value",
" when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if n == 31 then",
" if memop != MemOp_PREFETCH then CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"if ! postindex then",
" address = address + offset;",
"",
"case memop of",
" when MemOp_STORE",
" if rt_unknown then",
" data = bits(datasize) UNKNOWN;",
" else",
" data = X[t];",
" Mem[address, datasize DIV 8, acctype] = data;",
"",
" when MemOp_LOAD",
" data = Mem[address, datasize DIV 8, acctype];",
" if signed then",
" X[t] = SignExtend(data, regsize);",
" else",
" X[t] = ZeroExtend(data, regsize);",
"",
" when MemOp_PREFETCH",
" Prefetch(address, t<4:0>);",
"",
"if wback then",
" if wb_unknown then",
" address = bits(64) UNKNOWN;",
" elsif postindex then",
" address = address + offset;",
" if n == 31 then",
" SP[] = address;",
" else",
" X[n] = address;"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 opc#2 0 imm9#9 0 1 Rn#5 Rt#5",
"formats": [
{
"condition": "opc == 11",
"format": "LDRSB <Wt>, [<Xn|SP>], #<simm>"
},
{
"condition": "opc == 10",
"format": "LDRSB <Xt>, [<Xn|SP>], #<simm>"
}
],
"decoder": [
"boolean wback = TRUE;",
"boolean postindex = TRUE;",
"integer scale = UInt(size);",
"bits(64) offset = SignExtend(imm9, 64);integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"AccType acctype = AccType_NORMAL;",
"MemOp memop;",
"boolean signed;",
"integer regsize;",
"",
"if opc<1> == '0' then",
" // store or zero-extending load",
" memop = if opc<0> == '1' then MemOp_LOAD else MemOp_STORE;",
" regsize = if size == '11' then 64 else 32;",
" signed = FALSE;",
"else",
" if size == '11' then",
" UnallocatedEncoding();",
" else",
" // sign-extending load",
" memop = MemOp_LOAD;",
" if size == '10' && opc<0> == '1' then UnallocatedEncoding();",
" regsize = if opc<0> == '1' then 32 else 64;",
" signed = TRUE;",
"",
"integer datasize = 8 << scale;"
]
},
{
"pattern": "size#2 1 1 1 V#1 0 0 opc#2 0 imm9#9 1 1 Rn#5 Rt#5",
"formats": [
{
"condition": "opc == 11",
"format": "LDRSB <Wt>, [<Xn|SP>, #<simm>]!"
},
{
"condition": "opc == 10",
"format": "LDRSB <Xt>, [<Xn|SP>, #<simm>]!"
}
],
"decoder": [
"boolean wback = TRUE;",
"boolean postindex = FALSE;",
"integer scale = UInt(size);",
"bits(64) offset = SignExtend(imm9, 64);integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"AccType acctype = AccType_NORMAL;",
"MemOp memop;",
"boolean signed;",
"integer regsize;",
"",
"if opc<1> == '0' then",
" // store or zero-extending load",
" memop = if opc<0> == '1' then MemOp_LOAD else MemOp_STORE;",
" regsize = if size == '11' then 64 else 32;",
" signed = FALSE;",
"else",
" if size == '11' then",
" UnallocatedEncoding();",
" else",
" // sign-extending load",
" memop = MemOp_LOAD;",
" if size == '10' && opc<0> == '1' then UnallocatedEncoding();",
" regsize = if opc<0> == '1' then 32 else 64;",
" signed = TRUE;",
"",
"integer datasize = 8 << scale;"
]
},
{
"pattern": "size#2 1 1 1 V#1 0 1 opc#2 imm12#12 Rn#5 Rt#5",
"formats": [
{
"condition": "opc == 11",
"format": "LDRSB <Wt>, [<Xn|SP>{, #<pimm>}]"
},
{
"condition": "opc == 10",
"format": "LDRSB <Xt>, [<Xn|SP>{, #<pimm>}]"
}
],
"decoder": [
"boolean wback = FALSE;",
"boolean postindex = FALSE;",
"integer scale = UInt(size);",
"bits(64) offset = LSL(ZeroExtend(imm12, 64), scale);integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"AccType acctype = AccType_NORMAL;",
"MemOp memop;",
"boolean signed;",
"integer regsize;",
"",
"if opc<1> == '0' then",
" // store or zero-extending load",
" memop = if opc<0> == '1' then MemOp_LOAD else MemOp_STORE;",
" regsize = if size == '11' then 64 else 32;",
" signed = FALSE;",
"else",
" if size == '11' then",
" UnallocatedEncoding();",
" else",
" // sign-extending load",
" memop = MemOp_LOAD;",
" if size == '10' && opc<0> == '1' then UnallocatedEncoding();",
" regsize = if opc<0> == '1' then 32 else 64;",
" signed = TRUE;",
"",
"integer datasize = 8 << scale;"
]
}
],
"name": "LDRSB (immediate)",
"description": [
"Load Register Signed Byte (immediate)"
]
}
{
"operation": [
"bits(64) offset = ExtendReg(m, extend_type, shift);",
"bits(64) address;",
"bits(datasize) data;",
"boolean wb_unknown = FALSE;",
"boolean rt_unknown = FALSE;",
"",
"if memop == MemOp_LOAD && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD);",
" assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed",
" when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if memop == MemOp_STORE && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST);",
" assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_NONE rt_unknown = FALSE; // value stored is original value",
" when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if n == 31 then",
" if memop != MemOp_PREFETCH then CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"if ! postindex then",
" address = address + offset;",
"",
"case memop of",
" when MemOp_STORE",
" if rt_unknown then",
" data = bits(datasize) UNKNOWN;",
" else",
" data = X[t];",
" Mem[address, datasize DIV 8, acctype] = data;",
"",
" when MemOp_LOAD",
" data = Mem[address, datasize DIV 8, acctype];",
" if signed then",
" X[t] = SignExtend(data, regsize);",
" else",
" X[t] = ZeroExtend(data, regsize);",
"",
" when MemOp_PREFETCH",
" Prefetch(address, t<4:0>);",
"",
"if wback then",
" if wb_unknown then",
" address = bits(64) UNKNOWN;",
" elsif postindex then",
" address = address + offset;",
" if n == 31 then",
" SP[] = address;",
" else",
" X[n] = address;"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 opc#2 1 Rm#5 option#3 S#1 1 0 Rn#5 Rt#5",
"formats": [
{
"condition": "opc == 11 && option != 011",
"format": "LDRSB <Wt>, [<Xn|SP>, (<Wm>|<Xm>), <extend> {<amount>}]"
},
{
"condition": "opc == 11 && option == 011",
"format": "LDRSB <Wt>, [<Xn|SP>, <Xm>{, LSL <amount>}]"
},
{
"condition": "opc == 10 && option != 011",
"format": "LDRSB <Xt>, [<Xn|SP>, (<Wm>|<Xm>), <extend> {<amount>}]"
},
{
"condition": "opc == 10 && option == 011",
"format": "LDRSB <Xt>, [<Xn|SP>, <Xm>{, LSL <amount>}]"
}
],
"decoder": [
"boolean wback = FALSE;",
"boolean postindex = FALSE;",
"integer scale = UInt(size);",
"if option<1> == '0' then UnallocatedEncoding(); // sub-word index",
"ExtendType extend_type = DecodeRegExtend(option);",
"integer shift = if S == '1' then scale else 0;integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"integer m = UInt(Rm);",
"AccType acctype = AccType_NORMAL;",
"MemOp memop;",
"boolean signed;",
"integer regsize;",
"",
"if opc<1> == '0' then",
" // store or zero-extending load",
" memop = if opc<0> == '1' then MemOp_LOAD else MemOp_STORE;",
" regsize = if size == '11' then 64 else 32;",
" signed = FALSE;",
"else",
" if size == '11' then",
" memop = MemOp_PREFETCH;",
" if opc<0> == '1' then UnallocatedEncoding();",
" else",
" // sign-extending load",
" memop = MemOp_LOAD;",
" if size == '10' && opc<0> == '1' then UnallocatedEncoding();",
" regsize = if opc<0> == '1' then 32 else 64;",
" signed = TRUE;",
"",
"integer datasize = 8 << scale;"
]
}
],
"name": "LDRSB (register)",
"description": [
"Load Register Signed Byte (register)"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) data;",
"boolean wb_unknown = FALSE;",
"boolean rt_unknown = FALSE;",
"",
"if memop == MemOp_LOAD && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD);",
" assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed",
" when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if memop == MemOp_STORE && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST);",
" assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_NONE rt_unknown = FALSE; // value stored is original value",
" when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if n == 31 then",
" if memop != MemOp_PREFETCH then CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"if ! postindex then",
" address = address + offset;",
"",
"case memop of",
" when MemOp_STORE",
" if rt_unknown then",
" data = bits(datasize) UNKNOWN;",
" else",
" data = X[t];",
" Mem[address, datasize DIV 8, acctype] = data;",
"",
" when MemOp_LOAD",
" data = Mem[address, datasize DIV 8, acctype];",
" if signed then",
" X[t] = SignExtend(data, regsize);",
" else",
" X[t] = ZeroExtend(data, regsize);",
"",
" when MemOp_PREFETCH",
" Prefetch(address, t<4:0>);",
"",
"if wback then",
" if wb_unknown then",
" address = bits(64) UNKNOWN;",
" elsif postindex then",
" address = address + offset;",
" if n == 31 then",
" SP[] = address;",
" else",
" X[n] = address;"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 opc#2 0 imm9#9 0 1 Rn#5 Rt#5",
"formats": [
{
"condition": "opc == 11",
"format": "LDRSH <Wt>, [<Xn|SP>], #<simm>"
},
{
"condition": "opc == 10",
"format": "LDRSH <Xt>, [<Xn|SP>], #<simm>"
}
],
"decoder": [
"boolean wback = TRUE;",
"boolean postindex = TRUE;",
"integer scale = UInt(size);",
"bits(64) offset = SignExtend(imm9, 64);integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"AccType acctype = AccType_NORMAL;",
"MemOp memop;",
"boolean signed;",
"integer regsize;",
"",
"if opc<1> == '0' then",
" // store or zero-extending load",
" memop = if opc<0> == '1' then MemOp_LOAD else MemOp_STORE;",
" regsize = if size == '11' then 64 else 32;",
" signed = FALSE;",
"else",
" if size == '11' then",
" UnallocatedEncoding();",
" else",
" // sign-extending load",
" memop = MemOp_LOAD;",
" if size == '10' && opc<0> == '1' then UnallocatedEncoding();",
" regsize = if opc<0> == '1' then 32 else 64;",
" signed = TRUE;",
"",
"integer datasize = 8 << scale;"
]
},
{
"pattern": "size#2 1 1 1 V#1 0 0 opc#2 0 imm9#9 1 1 Rn#5 Rt#5",
"formats": [
{
"condition": "opc == 11",
"format": "LDRSH <Wt>, [<Xn|SP>, #<simm>]!"
},
{
"condition": "opc == 10",
"format": "LDRSH <Xt>, [<Xn|SP>, #<simm>]!"
}
],
"decoder": [
"boolean wback = TRUE;",
"boolean postindex = FALSE;",
"integer scale = UInt(size);",
"bits(64) offset = SignExtend(imm9, 64);integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"AccType acctype = AccType_NORMAL;",
"MemOp memop;",
"boolean signed;",
"integer regsize;",
"",
"if opc<1> == '0' then",
" // store or zero-extending load",
" memop = if opc<0> == '1' then MemOp_LOAD else MemOp_STORE;",
" regsize = if size == '11' then 64 else 32;",
" signed = FALSE;",
"else",
" if size == '11' then",
" UnallocatedEncoding();",
" else",
" // sign-extending load",
" memop = MemOp_LOAD;",
" if size == '10' && opc<0> == '1' then UnallocatedEncoding();",
" regsize = if opc<0> == '1' then 32 else 64;",
" signed = TRUE;",
"",
"integer datasize = 8 << scale;"
]
},
{
"pattern": "size#2 1 1 1 V#1 0 1 opc#2 imm12#12 Rn#5 Rt#5",
"formats": [
{
"condition": "opc == 11",
"format": "LDRSH <Wt>, [<Xn|SP>{, #<pimm>}]"
},
{
"condition": "opc == 10",
"format": "LDRSH <Xt>, [<Xn|SP>{, #<pimm>}]"
}
],
"decoder": [
"boolean wback = FALSE;",
"boolean postindex = FALSE;",
"integer scale = UInt(size);",
"bits(64) offset = LSL(ZeroExtend(imm12, 64), scale);integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"AccType acctype = AccType_NORMAL;",
"MemOp memop;",
"boolean signed;",
"integer regsize;",
"",
"if opc<1> == '0' then",
" // store or zero-extending load",
" memop = if opc<0> == '1' then MemOp_LOAD else MemOp_STORE;",
" regsize = if size == '11' then 64 else 32;",
" signed = FALSE;",
"else",
" if size == '11' then",
" UnallocatedEncoding();",
" else",
" // sign-extending load",
" memop = MemOp_LOAD;",
" if size == '10' && opc<0> == '1' then UnallocatedEncoding();",
" regsize = if opc<0> == '1' then 32 else 64;",
" signed = TRUE;",
"",
"integer datasize = 8 << scale;"
]
}
],
"name": "LDRSH (immediate)",
"description": [
"Load Register Signed Halfword (immediate)"
]
}
{
"operation": [
"bits(64) offset = ExtendReg(m, extend_type, shift);",
"bits(64) address;",
"bits(datasize) data;",
"boolean wb_unknown = FALSE;",
"boolean rt_unknown = FALSE;",
"",
"if memop == MemOp_LOAD && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD);",
" assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed",
" when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if memop == MemOp_STORE && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST);",
" assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_NONE rt_unknown = FALSE; // value stored is original value",
" when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if n == 31 then",
" if memop != MemOp_PREFETCH then CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"if ! postindex then",
" address = address + offset;",
"",
"case memop of",
" when MemOp_STORE",
" if rt_unknown then",
" data = bits(datasize) UNKNOWN;",
" else",
" data = X[t];",
" Mem[address, datasize DIV 8, acctype] = data;",
"",
" when MemOp_LOAD",
" data = Mem[address, datasize DIV 8, acctype];",
" if signed then",
" X[t] = SignExtend(data, regsize);",
" else",
" X[t] = ZeroExtend(data, regsize);",
"",
" when MemOp_PREFETCH",
" Prefetch(address, t<4:0>);",
"",
"if wback then",
" if wb_unknown then",
" address = bits(64) UNKNOWN;",
" elsif postindex then",
" address = address + offset;",
" if n == 31 then",
" SP[] = address;",
" else",
" X[n] = address;"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 opc#2 1 Rm#5 option#3 S#1 1 0 Rn#5 Rt#5",
"formats": [
{
"condition": "opc == 11",
"format": "LDRSH <Wt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]"
},
{
"condition": "opc == 10",
"format": "LDRSH <Xt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]"
}
],
"decoder": [
"boolean wback = FALSE;",
"boolean postindex = FALSE;",
"integer scale = UInt(size);",
"if option<1> == '0' then UnallocatedEncoding(); // sub-word index",
"ExtendType extend_type = DecodeRegExtend(option);",
"integer shift = if S == '1' then scale else 0;integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"integer m = UInt(Rm);",
"AccType acctype = AccType_NORMAL;",
"MemOp memop;",
"boolean signed;",
"integer regsize;",
"",
"if opc<1> == '0' then",
" // store or zero-extending load",
" memop = if opc<0> == '1' then MemOp_LOAD else MemOp_STORE;",
" regsize = if size == '11' then 64 else 32;",
" signed = FALSE;",
"else",
" if size == '11' then",
" memop = MemOp_PREFETCH;",
" if opc<0> == '1' then UnallocatedEncoding();",
" else",
" // sign-extending load",
" memop = MemOp_LOAD;",
" if size == '10' && opc<0> == '1' then UnallocatedEncoding();",
" regsize = if opc<0> == '1' then 32 else 64;",
" signed = TRUE;",
"",
"integer datasize = 8 << scale;"
]
}
],
"name": "LDRSH (register)",
"description": [
"Load Register Signed Halfword (register)"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) data;",
"boolean wb_unknown = FALSE;",
"boolean rt_unknown = FALSE;",
"",
"if memop == MemOp_LOAD && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD);",
" assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed",
" when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if memop == MemOp_STORE && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST);",
" assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_NONE rt_unknown = FALSE; // value stored is original value",
" when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if n == 31 then",
" if memop != MemOp_PREFETCH then CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"if ! postindex then",
" address = address + offset;",
"",
"case memop of",
" when MemOp_STORE",
" if rt_unknown then",
" data = bits(datasize) UNKNOWN;",
" else",
" data = X[t];",
" Mem[address, datasize DIV 8, acctype] = data;",
"",
" when MemOp_LOAD",
" data = Mem[address, datasize DIV 8, acctype];",
" if signed then",
" X[t] = SignExtend(data, regsize);",
" else",
" X[t] = ZeroExtend(data, regsize);",
"",
" when MemOp_PREFETCH",
" Prefetch(address, t<4:0>);",
"",
"if wback then",
" if wb_unknown then",
" address = bits(64) UNKNOWN;",
" elsif postindex then",
" address = address + offset;",
" if n == 31 then",
" SP[] = address;",
" else",
" X[n] = address;"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 opc#2 0 imm9#9 0 1 Rn#5 Rt#5",
"formats": [
{
"condition": null,
"format": "LDRSW <Xt>, [<Xn|SP>], #<simm>"
}
],
"decoder": [
"boolean wback = TRUE;",
"boolean postindex = TRUE;",
"integer scale = UInt(size);",
"bits(64) offset = SignExtend(imm9, 64);integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"AccType acctype = AccType_NORMAL;",
"MemOp memop;",
"boolean signed;",
"integer regsize;",
"",
"if opc<1> == '0' then",
" // store or zero-extending load",
" memop = if opc<0> == '1' then MemOp_LOAD else MemOp_STORE;",
" regsize = if size == '11' then 64 else 32;",
" signed = FALSE;",
"else",
" if size == '11' then",
" UnallocatedEncoding();",
" else",
" // sign-extending load",
" memop = MemOp_LOAD;",
" if size == '10' && opc<0> == '1' then UnallocatedEncoding();",
" regsize = if opc<0> == '1' then 32 else 64;",
" signed = TRUE;",
"",
"integer datasize = 8 << scale;"
]
},
{
"pattern": "size#2 1 1 1 V#1 0 0 opc#2 0 imm9#9 1 1 Rn#5 Rt#5",
"formats": [
{
"condition": null,
"format": "LDRSW <Xt>, [<Xn|SP>, #<simm>]!"
}
],
"decoder": [
"boolean wback = TRUE;",
"boolean postindex = FALSE;",
"integer scale = UInt(size);",
"bits(64) offset = SignExtend(imm9, 64);integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"AccType acctype = AccType_NORMAL;",
"MemOp memop;",
"boolean signed;",
"integer regsize;",
"",
"if opc<1> == '0' then",
" // store or zero-extending load",
" memop = if opc<0> == '1' then MemOp_LOAD else MemOp_STORE;",
" regsize = if size == '11' then 64 else 32;",
" signed = FALSE;",
"else",
" if size == '11' then",
" UnallocatedEncoding();",
" else",
" // sign-extending load",
" memop = MemOp_LOAD;",
" if size == '10' && opc<0> == '1' then UnallocatedEncoding();",
" regsize = if opc<0> == '1' then 32 else 64;",
" signed = TRUE;",
"",
"integer datasize = 8 << scale;"
]
},
{
"pattern": "size#2 1 1 1 V#1 0 1 opc#2 imm12#12 Rn#5 Rt#5",
"formats": [
{
"condition": null,
"format": "LDRSW <Xt>, [<Xn|SP>{, #<pimm>}]"
}
],
"decoder": [
"boolean wback = FALSE;",
"boolean postindex = FALSE;",
"integer scale = UInt(size);",
"bits(64) offset = LSL(ZeroExtend(imm12, 64), scale);integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"AccType acctype = AccType_NORMAL;",
"MemOp memop;",
"boolean signed;",
"integer regsize;",
"",
"if opc<1> == '0' then",
" // store or zero-extending load",
" memop = if opc<0> == '1' then MemOp_LOAD else MemOp_STORE;",
" regsize = if size == '11' then 64 else 32;",
" signed = FALSE;",
"else",
" if size == '11' then",
" UnallocatedEncoding();",
" else",
" // sign-extending load",
" memop = MemOp_LOAD;",
" if size == '10' && opc<0> == '1' then UnallocatedEncoding();",
" regsize = if opc<0> == '1' then 32 else 64;",
" signed = TRUE;",
"",
"integer datasize = 8 << scale;"
]
}
],
"name": "LDRSW (immediate)",
"description": [
"Load Register Signed Word (immediate)"
]
}
{
"operation": [
"bits(64) address = PC[] + offset;",
"bits(size*8) data;",
"",
"case memop of",
" when MemOp_LOAD",
" data = Mem[address, size, AccType_NORMAL];",
" if signed then",
" X[t] = SignExtend(data, 64);",
" else",
" X[t] = data;",
"",
" when MemOp_PREFETCH",
" Prefetch(address, t<4:0>);"
],
"variants": [
{
"pattern": "opc#2 0 1 1 V#1 0 0 imm19#19 Rt#5",
"formats": [
{
"condition": null,
"format": "LDRSW <Xt>, <label>"
}
],
"decoder": [
"integer t = UInt(Rt);",
"MemOp memop = MemOp_LOAD;",
"boolean signed = FALSE;",
"integer size;",
"bits(64) offset;",
"",
"case opc of",
" when '00'",
" size = 4;",
" when '01'",
" size = 8;",
" when '10'",
" size = 4;",
" signed = TRUE;",
" when '11'",
" memop = MemOp_PREFETCH;",
"",
"offset = SignExtend(imm19:'00', 64);"
]
}
],
"name": "LDRSW (literal)",
"description": [
"Load Register Signed Word (literal)"
]
}
{
"operation": [
"bits(64) offset = ExtendReg(m, extend_type, shift);",
"bits(64) address;",
"bits(datasize) data;",
"boolean wb_unknown = FALSE;",
"boolean rt_unknown = FALSE;",
"",
"if memop == MemOp_LOAD && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD);",
" assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed",
" when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if memop == MemOp_STORE && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST);",
" assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_NONE rt_unknown = FALSE; // value stored is original value",
" when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if n == 31 then",
" if memop != MemOp_PREFETCH then CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"if ! postindex then",
" address = address + offset;",
"",
"case memop of",
" when MemOp_STORE",
" if rt_unknown then",
" data = bits(datasize) UNKNOWN;",
" else",
" data = X[t];",
" Mem[address, datasize DIV 8, acctype] = data;",
"",
" when MemOp_LOAD",
" data = Mem[address, datasize DIV 8, acctype];",
" if signed then",
" X[t] = SignExtend(data, regsize);",
" else",
" X[t] = ZeroExtend(data, regsize);",
"",
" when MemOp_PREFETCH",
" Prefetch(address, t<4:0>);",
"",
"if wback then",
" if wb_unknown then",
" address = bits(64) UNKNOWN;",
" elsif postindex then",
" address = address + offset;",
" if n == 31 then",
" SP[] = address;",
" else",
" X[n] = address;"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 opc#2 1 Rm#5 option#3 S#1 1 0 Rn#5 Rt#5",
"formats": [
{
"condition": null,
"format": "LDRSW <Xt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]"
}
],
"decoder": [
"boolean wback = FALSE;",
"boolean postindex = FALSE;",
"integer scale = UInt(size);",
"if option<1> == '0' then UnallocatedEncoding(); // sub-word index",
"ExtendType extend_type = DecodeRegExtend(option);",
"integer shift = if S == '1' then scale else 0;integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"integer m = UInt(Rm);",
"AccType acctype = AccType_NORMAL;",
"MemOp memop;",
"boolean signed;",
"integer regsize;",
"",
"if opc<1> == '0' then",
" // store or zero-extending load",
" memop = if opc<0> == '1' then MemOp_LOAD else MemOp_STORE;",
" regsize = if size == '11' then 64 else 32;",
" signed = FALSE;",
"else",
" if size == '11' then",
" memop = MemOp_PREFETCH;",
" if opc<0> == '1' then UnallocatedEncoding();",
" else",
" // sign-extending load",
" memop = MemOp_LOAD;",
" if size == '10' && opc<0> == '1' then UnallocatedEncoding();",
" regsize = if opc<0> == '1' then 32 else 64;",
" signed = TRUE;",
"",
"integer datasize = 8 << scale;"
]
}
],
"name": "LDRSW (register)",
"description": [
"Load Register Signed Word (register)"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) value;",
"bits(datasize) data;",
"bits(datasize) result;",
"",
"value = X[s];",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"data = Mem[address, datasize DIV 8, ldacctype];",
"",
"case op of",
" when MemAtomicOp_ADD result = data + value;",
" when MemAtomicOp_BIC result = data AND NOT(value);",
" when MemAtomicOp_EOR result = data EOR value;",
" when MemAtomicOp_ORR result = data OR value;",
" when MemAtomicOp_SMAX result = if SInt(data) > SInt(value) then data else value;",
" when MemAtomicOp_SMIN result = if SInt(data) > SInt(value) then value else data;",
" when MemAtomicOp_UMAX result = if UInt(data) > UInt(value) then data else value;",
" when MemAtomicOp_UMIN result = if UInt(data) > UInt(value) then value else data;",
" when MemAtomicOp_SWP result = value;",
"",
"// All observers in the shareability domain observe the",
"// following load and store atomically.",
"Mem[address, datasize DIV 8, stacctype] = result;",
"",
"X[t] = ZeroExtend(data, regsize);"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 A#1 R#1 1 Rs#5 o3#1 opc#3 0 0 Rn#5 Rt#5",
"formats": [
{
"condition": "size == 10 && A == 1 && R == 0",
"format": "LDSETA <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "size == 10 && A == 1 && R == 1",
"format": "LDSETAL <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "size == 10 && A == 0 && R == 0 && Rt != 11111",
"format": "LDSET <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "size == 10 && A == 0 && R == 1 && Rt != 11111",
"format": "LDSETL <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "size == 11 && A == 1 && R == 0",
"format": "LDSETA <Xs>, <Xt>, [<Xn|SP>]"
},
{
"condition": "size == 11 && A == 1 && R == 1",
"format": "LDSETAL <Xs>, <Xt>, [<Xn|SP>]"
},
{
"condition": "size == 11 && A == 0 && R == 0 && Rt != 11111",
"format": "LDSET <Xs>, <Xt>, [<Xn|SP>]"
},
{
"condition": "size == 11 && A == 0 && R == 1 && Rt != 11111",
"format": "LDSETL <Xs>, <Xt>, [<Xn|SP>]"
}
],
"decoder": [
"if !HaveAtomicExt() then UnallocatedEncoding();",
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer s = UInt(Rs);",
"",
"integer datasize = 8 << UInt(size);",
"integer regsize = if datasize == 64 then 64 else 32;",
"AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"AccType stacctype = if R == '1' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"MemAtomicOp op;",
"case o3:opc of",
" when '0000' op = MemAtomicOp_ADD;",
" when '0001' op = MemAtomicOp_BIC;",
" when '0010' op = MemAtomicOp_EOR;",
" when '0011' op = MemAtomicOp_ORR;",
" when '0100' op = MemAtomicOp_SMAX;",
" when '0101' op = MemAtomicOp_SMIN;",
" when '0110' op = MemAtomicOp_UMAX;",
" when '0111' op = MemAtomicOp_UMIN;",
" when '1000' op = MemAtomicOp_SWP;",
" otherwise UnallocatedEncoding();"
]
}
],
"name": "LDSET, LDSETA, LDSETAL, LDSETL",
"description": [
"Atomic bit set on word or doubleword in memory"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) value;",
"bits(datasize) data;",
"bits(datasize) result;",
"",
"value = X[s];",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"data = Mem[address, datasize DIV 8, ldacctype];",
"",
"case op of",
" when MemAtomicOp_ADD result = data + value;",
" when MemAtomicOp_BIC result = data AND NOT(value);",
" when MemAtomicOp_EOR result = data EOR value;",
" when MemAtomicOp_ORR result = data OR value;",
" when MemAtomicOp_SMAX result = if SInt(data) > SInt(value) then data else value;",
" when MemAtomicOp_SMIN result = if SInt(data) > SInt(value) then value else data;",
" when MemAtomicOp_UMAX result = if UInt(data) > UInt(value) then data else value;",
" when MemAtomicOp_UMIN result = if UInt(data) > UInt(value) then value else data;",
" when MemAtomicOp_SWP result = value;",
"",
"// All observers in the shareability domain observe the",
"// following load and store atomically.",
"Mem[address, datasize DIV 8, stacctype] = result;",
"",
"X[t] = ZeroExtend(data, regsize);"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 A#1 R#1 1 Rs#5 o3#1 opc#3 0 0 Rn#5 Rt#5",
"formats": [
{
"condition": "A == 1 && R == 0",
"format": "LDSETAB <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 1 && R == 1",
"format": "LDSETALB <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 0 && R == 0 && Rt != 11111",
"format": "LDSETB <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 0 && R == 1 && Rt != 11111",
"format": "LDSETLB <Ws>, <Wt>, [<Xn|SP>]"
}
],
"decoder": [
"if !HaveAtomicExt() then UnallocatedEncoding();",
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer s = UInt(Rs);",
"",
"integer datasize = 8 << UInt(size);",
"integer regsize = if datasize == 64 then 64 else 32;",
"AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"AccType stacctype = if R == '1' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"MemAtomicOp op;",
"case o3:opc of",
" when '0000' op = MemAtomicOp_ADD;",
" when '0001' op = MemAtomicOp_BIC;",
" when '0010' op = MemAtomicOp_EOR;",
" when '0011' op = MemAtomicOp_ORR;",
" when '0100' op = MemAtomicOp_SMAX;",
" when '0101' op = MemAtomicOp_SMIN;",
" when '0110' op = MemAtomicOp_UMAX;",
" when '0111' op = MemAtomicOp_UMIN;",
" when '1000' op = MemAtomicOp_SWP;",
" otherwise UnallocatedEncoding();"
]
}
],
"name": "LDSETB, LDSETAB, LDSETALB, LDSETLB",
"description": [
"Atomic bit set on byte in memory"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) value;",
"bits(datasize) data;",
"bits(datasize) result;",
"",
"value = X[s];",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"data = Mem[address, datasize DIV 8, ldacctype];",
"",
"case op of",
" when MemAtomicOp_ADD result = data + value;",
" when MemAtomicOp_BIC result = data AND NOT(value);",
" when MemAtomicOp_EOR result = data EOR value;",
" when MemAtomicOp_ORR result = data OR value;",
" when MemAtomicOp_SMAX result = if SInt(data) > SInt(value) then data else value;",
" when MemAtomicOp_SMIN result = if SInt(data) > SInt(value) then value else data;",
" when MemAtomicOp_UMAX result = if UInt(data) > UInt(value) then data else value;",
" when MemAtomicOp_UMIN result = if UInt(data) > UInt(value) then value else data;",
" when MemAtomicOp_SWP result = value;",
"",
"// All observers in the shareability domain observe the",
"// following load and store atomically.",
"Mem[address, datasize DIV 8, stacctype] = result;",
"",
"X[t] = ZeroExtend(data, regsize);"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 A#1 R#1 1 Rs#5 o3#1 opc#3 0 0 Rn#5 Rt#5",
"formats": [
{
"condition": "A == 1 && R == 0",
"format": "LDSETAH <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 1 && R == 1",
"format": "LDSETALH <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 0 && R == 0 && Rt != 11111",
"format": "LDSETH <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 0 && R == 1 && Rt != 11111",
"format": "LDSETLH <Ws>, <Wt>, [<Xn|SP>]"
}
],
"decoder": [
"if !HaveAtomicExt() then UnallocatedEncoding();",
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer s = UInt(Rs);",
"",
"integer datasize = 8 << UInt(size);",
"integer regsize = if datasize == 64 then 64 else 32;",
"AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"AccType stacctype = if R == '1' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"MemAtomicOp op;",
"case o3:opc of",
" when '0000' op = MemAtomicOp_ADD;",
" when '0001' op = MemAtomicOp_BIC;",
" when '0010' op = MemAtomicOp_EOR;",
" when '0011' op = MemAtomicOp_ORR;",
" when '0100' op = MemAtomicOp_SMAX;",
" when '0101' op = MemAtomicOp_SMIN;",
" when '0110' op = MemAtomicOp_UMAX;",
" when '0111' op = MemAtomicOp_UMIN;",
" when '1000' op = MemAtomicOp_SWP;",
" otherwise UnallocatedEncoding();"
]
}
],
"name": "LDSETH, LDSETAH, LDSETALH, LDSETLH",
"description": [
"Atomic bit set on halfword in memory"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) value;",
"bits(datasize) data;",
"bits(datasize) result;",
"",
"value = X[s];",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"data = Mem[address, datasize DIV 8, ldacctype];",
"",
"case op of",
" when MemAtomicOp_ADD result = data + value;",
" when MemAtomicOp_BIC result = data AND NOT(value);",
" when MemAtomicOp_EOR result = data EOR value;",
" when MemAtomicOp_ORR result = data OR value;",
" when MemAtomicOp_SMAX result = if SInt(data) > SInt(value) then data else value;",
" when MemAtomicOp_SMIN result = if SInt(data) > SInt(value) then value else data;",
" when MemAtomicOp_UMAX result = if UInt(data) > UInt(value) then data else value;",
" when MemAtomicOp_UMIN result = if UInt(data) > UInt(value) then value else data;",
" when MemAtomicOp_SWP result = value;",
"",
"// All observers in the shareability domain observe the",
"// following load and store atomically.",
"Mem[address, datasize DIV 8, stacctype] = result;",
"",
"X[t] = ZeroExtend(data, regsize);"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 A#1 R#1 1 Rs#5 o3#1 opc#3 0 0 Rn#5 Rt#5",
"formats": [
{
"condition": "size == 10 && A == 1 && R == 0",
"format": "LDSMAXA <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "size == 10 && A == 1 && R == 1",
"format": "LDSMAXAL <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "size == 10 && A == 0 && R == 0 && Rt != 11111",
"format": "LDSMAX <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "size == 10 && A == 0 && R == 1 && Rt != 11111",
"format": "LDSMAXL <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "size == 11 && A == 1 && R == 0",
"format": "LDSMAXA <Xs>, <Xt>, [<Xn|SP>]"
},
{
"condition": "size == 11 && A == 1 && R == 1",
"format": "LDSMAXAL <Xs>, <Xt>, [<Xn|SP>]"
},
{
"condition": "size == 11 && A == 0 && R == 0 && Rt != 11111",
"format": "LDSMAX <Xs>, <Xt>, [<Xn|SP>]"
},
{
"condition": "size == 11 && A == 0 && R == 1 && Rt != 11111",
"format": "LDSMAXL <Xs>, <Xt>, [<Xn|SP>]"
}
],
"decoder": [
"if !HaveAtomicExt() then UnallocatedEncoding();",
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer s = UInt(Rs);",
"",
"integer datasize = 8 << UInt(size);",
"integer regsize = if datasize == 64 then 64 else 32;",
"AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"AccType stacctype = if R == '1' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"MemAtomicOp op;",
"case o3:opc of",
" when '0000' op = MemAtomicOp_ADD;",
" when '0001' op = MemAtomicOp_BIC;",
" when '0010' op = MemAtomicOp_EOR;",
" when '0011' op = MemAtomicOp_ORR;",
" when '0100' op = MemAtomicOp_SMAX;",
" when '0101' op = MemAtomicOp_SMIN;",
" when '0110' op = MemAtomicOp_UMAX;",
" when '0111' op = MemAtomicOp_UMIN;",
" when '1000' op = MemAtomicOp_SWP;",
" otherwise UnallocatedEncoding();"
]
}
],
"name": "LDSMAX, LDSMAXA, LDSMAXAL, LDSMAXL",
"description": [
"Atomic signed maximum on word or doubleword in memory"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) value;",
"bits(datasize) data;",
"bits(datasize) result;",
"",
"value = X[s];",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"data = Mem[address, datasize DIV 8, ldacctype];",
"",
"case op of",
" when MemAtomicOp_ADD result = data + value;",
" when MemAtomicOp_BIC result = data AND NOT(value);",
" when MemAtomicOp_EOR result = data EOR value;",
" when MemAtomicOp_ORR result = data OR value;",
" when MemAtomicOp_SMAX result = if SInt(data) > SInt(value) then data else value;",
" when MemAtomicOp_SMIN result = if SInt(data) > SInt(value) then value else data;",
" when MemAtomicOp_UMAX result = if UInt(data) > UInt(value) then data else value;",
" when MemAtomicOp_UMIN result = if UInt(data) > UInt(value) then value else data;",
" when MemAtomicOp_SWP result = value;",
"",
"// All observers in the shareability domain observe the",
"// following load and store atomically.",
"Mem[address, datasize DIV 8, stacctype] = result;",
"",
"X[t] = ZeroExtend(data, regsize);"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 A#1 R#1 1 Rs#5 o3#1 opc#3 0 0 Rn#5 Rt#5",
"formats": [
{
"condition": "A == 1 && R == 0",
"format": "LDSMAXAB <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 1 && R == 1",
"format": "LDSMAXALB <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 0 && R == 0 && Rt != 11111",
"format": "LDSMAXB <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 0 && R == 1 && Rt != 11111",
"format": "LDSMAXLB <Ws>, <Wt>, [<Xn|SP>]"
}
],
"decoder": [
"if !HaveAtomicExt() then UnallocatedEncoding();",
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer s = UInt(Rs);",
"",
"integer datasize = 8 << UInt(size);",
"integer regsize = if datasize == 64 then 64 else 32;",
"AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"AccType stacctype = if R == '1' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"MemAtomicOp op;",
"case o3:opc of",
" when '0000' op = MemAtomicOp_ADD;",
" when '0001' op = MemAtomicOp_BIC;",
" when '0010' op = MemAtomicOp_EOR;",
" when '0011' op = MemAtomicOp_ORR;",
" when '0100' op = MemAtomicOp_SMAX;",
" when '0101' op = MemAtomicOp_SMIN;",
" when '0110' op = MemAtomicOp_UMAX;",
" when '0111' op = MemAtomicOp_UMIN;",
" when '1000' op = MemAtomicOp_SWP;",
" otherwise UnallocatedEncoding();"
]
}
],
"name": "LDSMAXB, LDSMAXAB, LDSMAXALB, LDSMAXLB",
"description": [
"Atomic signed maximum on byte in memory"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) value;",
"bits(datasize) data;",
"bits(datasize) result;",
"",
"value = X[s];",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"data = Mem[address, datasize DIV 8, ldacctype];",
"",
"case op of",
" when MemAtomicOp_ADD result = data + value;",
" when MemAtomicOp_BIC result = data AND NOT(value);",
" when MemAtomicOp_EOR result = data EOR value;",
" when MemAtomicOp_ORR result = data OR value;",
" when MemAtomicOp_SMAX result = if SInt(data) > SInt(value) then data else value;",
" when MemAtomicOp_SMIN result = if SInt(data) > SInt(value) then value else data;",
" when MemAtomicOp_UMAX result = if UInt(data) > UInt(value) then data else value;",
" when MemAtomicOp_UMIN result = if UInt(data) > UInt(value) then value else data;",
" when MemAtomicOp_SWP result = value;",
"",
"// All observers in the shareability domain observe the",
"// following load and store atomically.",
"Mem[address, datasize DIV 8, stacctype] = result;",
"",
"X[t] = ZeroExtend(data, regsize);"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 A#1 R#1 1 Rs#5 o3#1 opc#3 0 0 Rn#5 Rt#5",
"formats": [
{
"condition": "A == 1 && R == 0",
"format": "LDSMAXAH <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 1 && R == 1",
"format": "LDSMAXALH <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 0 && R == 0 && Rt != 11111",
"format": "LDSMAXH <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 0 && R == 1 && Rt != 11111",
"format": "LDSMAXLH <Ws>, <Wt>, [<Xn|SP>]"
}
],
"decoder": [
"if !HaveAtomicExt() then UnallocatedEncoding();",
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer s = UInt(Rs);",
"",
"integer datasize = 8 << UInt(size);",
"integer regsize = if datasize == 64 then 64 else 32;",
"AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"AccType stacctype = if R == '1' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"MemAtomicOp op;",
"case o3:opc of",
" when '0000' op = MemAtomicOp_ADD;",
" when '0001' op = MemAtomicOp_BIC;",
" when '0010' op = MemAtomicOp_EOR;",
" when '0011' op = MemAtomicOp_ORR;",
" when '0100' op = MemAtomicOp_SMAX;",
" when '0101' op = MemAtomicOp_SMIN;",
" when '0110' op = MemAtomicOp_UMAX;",
" when '0111' op = MemAtomicOp_UMIN;",
" when '1000' op = MemAtomicOp_SWP;",
" otherwise UnallocatedEncoding();"
]
}
],
"name": "LDSMAXH, LDSMAXAH, LDSMAXALH, LDSMAXLH",
"description": [
"Atomic signed maximum on halfword in memory"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) value;",
"bits(datasize) data;",
"bits(datasize) result;",
"",
"value = X[s];",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"data = Mem[address, datasize DIV 8, ldacctype];",
"",
"case op of",
" when MemAtomicOp_ADD result = data + value;",
" when MemAtomicOp_BIC result = data AND NOT(value);",
" when MemAtomicOp_EOR result = data EOR value;",
" when MemAtomicOp_ORR result = data OR value;",
" when MemAtomicOp_SMAX result = if SInt(data) > SInt(value) then data else value;",
" when MemAtomicOp_SMIN result = if SInt(data) > SInt(value) then value else data;",
" when MemAtomicOp_UMAX result = if UInt(data) > UInt(value) then data else value;",
" when MemAtomicOp_UMIN result = if UInt(data) > UInt(value) then value else data;",
" when MemAtomicOp_SWP result = value;",
"",
"// All observers in the shareability domain observe the",
"// following load and store atomically.",
"Mem[address, datasize DIV 8, stacctype] = result;",
"",
"X[t] = ZeroExtend(data, regsize);"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 A#1 R#1 1 Rs#5 o3#1 opc#3 0 0 Rn#5 Rt#5",
"formats": [
{
"condition": "size == 10 && A == 1 && R == 0",
"format": "LDSMINA <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "size == 10 && A == 1 && R == 1",
"format": "LDSMINAL <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "size == 10 && A == 0 && R == 0 && Rt != 11111",
"format": "LDSMIN <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "size == 10 && A == 0 && R == 1 && Rt != 11111",
"format": "LDSMINL <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "size == 11 && A == 1 && R == 0",
"format": "LDSMINA <Xs>, <Xt>, [<Xn|SP>]"
},
{
"condition": "size == 11 && A == 1 && R == 1",
"format": "LDSMINAL <Xs>, <Xt>, [<Xn|SP>]"
},
{
"condition": "size == 11 && A == 0 && R == 0 && Rt != 11111",
"format": "LDSMIN <Xs>, <Xt>, [<Xn|SP>]"
},
{
"condition": "size == 11 && A == 0 && R == 1 && Rt != 11111",
"format": "LDSMINL <Xs>, <Xt>, [<Xn|SP>]"
}
],
"decoder": [
"if !HaveAtomicExt() then UnallocatedEncoding();",
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer s = UInt(Rs);",
"",
"integer datasize = 8 << UInt(size);",
"integer regsize = if datasize == 64 then 64 else 32;",
"AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"AccType stacctype = if R == '1' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"MemAtomicOp op;",
"case o3:opc of",
" when '0000' op = MemAtomicOp_ADD;",
" when '0001' op = MemAtomicOp_BIC;",
" when '0010' op = MemAtomicOp_EOR;",
" when '0011' op = MemAtomicOp_ORR;",
" when '0100' op = MemAtomicOp_SMAX;",
" when '0101' op = MemAtomicOp_SMIN;",
" when '0110' op = MemAtomicOp_UMAX;",
" when '0111' op = MemAtomicOp_UMIN;",
" when '1000' op = MemAtomicOp_SWP;",
" otherwise UnallocatedEncoding();"
]
}
],
"name": "LDSMIN, LDSMINA, LDSMINAL, LDSMINL",
"description": [
"Atomic signed minimum on word or doubleword in memory"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) value;",
"bits(datasize) data;",
"bits(datasize) result;",
"",
"value = X[s];",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"data = Mem[address, datasize DIV 8, ldacctype];",
"",
"case op of",
" when MemAtomicOp_ADD result = data + value;",
" when MemAtomicOp_BIC result = data AND NOT(value);",
" when MemAtomicOp_EOR result = data EOR value;",
" when MemAtomicOp_ORR result = data OR value;",
" when MemAtomicOp_SMAX result = if SInt(data) > SInt(value) then data else value;",
" when MemAtomicOp_SMIN result = if SInt(data) > SInt(value) then value else data;",
" when MemAtomicOp_UMAX result = if UInt(data) > UInt(value) then data else value;",
" when MemAtomicOp_UMIN result = if UInt(data) > UInt(value) then value else data;",
" when MemAtomicOp_SWP result = value;",
"",
"// All observers in the shareability domain observe the",
"// following load and store atomically.",
"Mem[address, datasize DIV 8, stacctype] = result;",
"",
"X[t] = ZeroExtend(data, regsize);"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 A#1 R#1 1 Rs#5 o3#1 opc#3 0 0 Rn#5 Rt#5",
"formats": [
{
"condition": "A == 1 && R == 0",
"format": "LDSMINAB <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 1 && R == 1",
"format": "LDSMINALB <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 0 && R == 0 && Rt != 11111",
"format": "LDSMINB <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 0 && R == 1 && Rt != 11111",
"format": "LDSMINLB <Ws>, <Wt>, [<Xn|SP>]"
}
],
"decoder": [
"if !HaveAtomicExt() then UnallocatedEncoding();",
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer s = UInt(Rs);",
"",
"integer datasize = 8 << UInt(size);",
"integer regsize = if datasize == 64 then 64 else 32;",
"AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"AccType stacctype = if R == '1' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"MemAtomicOp op;",
"case o3:opc of",
" when '0000' op = MemAtomicOp_ADD;",
" when '0001' op = MemAtomicOp_BIC;",
" when '0010' op = MemAtomicOp_EOR;",
" when '0011' op = MemAtomicOp_ORR;",
" when '0100' op = MemAtomicOp_SMAX;",
" when '0101' op = MemAtomicOp_SMIN;",
" when '0110' op = MemAtomicOp_UMAX;",
" when '0111' op = MemAtomicOp_UMIN;",
" when '1000' op = MemAtomicOp_SWP;",
" otherwise UnallocatedEncoding();"
]
}
],
"name": "LDSMINB, LDSMINAB, LDSMINALB, LDSMINLB",
"description": [
"Atomic signed minimum on byte in memory"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) value;",
"bits(datasize) data;",
"bits(datasize) result;",
"",
"value = X[s];",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"data = Mem[address, datasize DIV 8, ldacctype];",
"",
"case op of",
" when MemAtomicOp_ADD result = data + value;",
" when MemAtomicOp_BIC result = data AND NOT(value);",
" when MemAtomicOp_EOR result = data EOR value;",
" when MemAtomicOp_ORR result = data OR value;",
" when MemAtomicOp_SMAX result = if SInt(data) > SInt(value) then data else value;",
" when MemAtomicOp_SMIN result = if SInt(data) > SInt(value) then value else data;",
" when MemAtomicOp_UMAX result = if UInt(data) > UInt(value) then data else value;",
" when MemAtomicOp_UMIN result = if UInt(data) > UInt(value) then value else data;",
" when MemAtomicOp_SWP result = value;",
"",
"// All observers in the shareability domain observe the",
"// following load and store atomically.",
"Mem[address, datasize DIV 8, stacctype] = result;",
"",
"X[t] = ZeroExtend(data, regsize);"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 A#1 R#1 1 Rs#5 o3#1 opc#3 0 0 Rn#5 Rt#5",
"formats": [
{
"condition": "A == 1 && R == 0",
"format": "LDSMINAH <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 1 && R == 1",
"format": "LDSMINALH <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 0 && R == 0 && Rt != 11111",
"format": "LDSMINH <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 0 && R == 1 && Rt != 11111",
"format": "LDSMINLH <Ws>, <Wt>, [<Xn|SP>]"
}
],
"decoder": [
"if !HaveAtomicExt() then UnallocatedEncoding();",
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer s = UInt(Rs);",
"",
"integer datasize = 8 << UInt(size);",
"integer regsize = if datasize == 64 then 64 else 32;",
"AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"AccType stacctype = if R == '1' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"MemAtomicOp op;",
"case o3:opc of",
" when '0000' op = MemAtomicOp_ADD;",
" when '0001' op = MemAtomicOp_BIC;",
" when '0010' op = MemAtomicOp_EOR;",
" when '0011' op = MemAtomicOp_ORR;",
" when '0100' op = MemAtomicOp_SMAX;",
" when '0101' op = MemAtomicOp_SMIN;",
" when '0110' op = MemAtomicOp_UMAX;",
" when '0111' op = MemAtomicOp_UMIN;",
" when '1000' op = MemAtomicOp_SWP;",
" otherwise UnallocatedEncoding();"
]
}
],
"name": "LDSMINH, LDSMINAH, LDSMINALH, LDSMINLH",
"description": [
"Atomic signed minimum on halfword in memory"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) data;",
"boolean wb_unknown = FALSE;",
"boolean rt_unknown = FALSE;",
"",
"if memop == MemOp_LOAD && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD);",
" assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed",
" when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if memop == MemOp_STORE && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST);",
" assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_NONE rt_unknown = FALSE; // value stored is original value",
" when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if n == 31 then",
" if memop != MemOp_PREFETCH then CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"if ! postindex then",
" address = address + offset;",
"",
"case memop of",
" when MemOp_STORE",
" if rt_unknown then",
" data = bits(datasize) UNKNOWN;",
" else",
" data = X[t];",
" Mem[address, datasize DIV 8, acctype] = data;",
"",
" when MemOp_LOAD",
" data = Mem[address, datasize DIV 8, acctype];",
" if signed then",
" X[t] = SignExtend(data, regsize);",
" else",
" X[t] = ZeroExtend(data, regsize);",
"",
" when MemOp_PREFETCH",
" Prefetch(address, t<4:0>);",
"",
"if wback then",
" if wb_unknown then",
" address = bits(64) UNKNOWN;",
" elsif postindex then",
" address = address + offset;",
" if n == 31 then",
" SP[] = address;",
" else",
" X[n] = address;"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 opc#2 0 imm9#9 1 0 Rn#5 Rt#5",
"formats": [
{
"condition": "size == 10",
"format": "LDTR <Wt>, [<Xn|SP>{, #<simm>}]"
},
{
"condition": "size == 11",
"format": "LDTR <Xt>, [<Xn|SP>{, #<simm>}]"
}
],
"decoder": [
"boolean wback = FALSE;",
"boolean postindex = FALSE;",
"integer scale = UInt(size);",
"bits(64) offset = SignExtend(imm9, 64);integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"AccType acctype = AccType_UNPRIV;",
"MemOp memop;",
"boolean signed;",
"integer regsize;",
"",
"if opc<1> == '0' then",
" // store or zero-extending load",
" memop = if opc<0> == '1' then MemOp_LOAD else MemOp_STORE;",
" regsize = if size == '11' then 64 else 32;",
" signed = FALSE;",
"else",
" if size == '11' then",
" UnallocatedEncoding();",
" else",
" // sign-extending load",
" memop = MemOp_LOAD;",
" if size == '10' && opc<0> == '1' then UnallocatedEncoding();",
" regsize = if opc<0> == '1' then 32 else 64;",
" signed = TRUE;",
"",
"integer datasize = 8 << scale;"
]
}
],
"name": "LDTR",
"description": [
"Load Register (unprivileged)"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) data;",
"boolean wb_unknown = FALSE;",
"boolean rt_unknown = FALSE;",
"",
"if memop == MemOp_LOAD && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD);",
" assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed",
" when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if memop == MemOp_STORE && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST);",
" assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_NONE rt_unknown = FALSE; // value stored is original value",
" when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if n == 31 then",
" if memop != MemOp_PREFETCH then CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"if ! postindex then",
" address = address + offset;",
"",
"case memop of",
" when MemOp_STORE",
" if rt_unknown then",
" data = bits(datasize) UNKNOWN;",
" else",
" data = X[t];",
" Mem[address, datasize DIV 8, acctype] = data;",
"",
" when MemOp_LOAD",
" data = Mem[address, datasize DIV 8, acctype];",
" if signed then",
" X[t] = SignExtend(data, regsize);",
" else",
" X[t] = ZeroExtend(data, regsize);",
"",
" when MemOp_PREFETCH",
" Prefetch(address, t<4:0>);",
"",
"if wback then",
" if wb_unknown then",
" address = bits(64) UNKNOWN;",
" elsif postindex then",
" address = address + offset;",
" if n == 31 then",
" SP[] = address;",
" else",
" X[n] = address;"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 opc#2 0 imm9#9 1 0 Rn#5 Rt#5",
"formats": [
{
"condition": null,
"format": "LDTRB <Wt>, [<Xn|SP>{, #<simm>}]"
}
],
"decoder": [
"boolean wback = FALSE;",
"boolean postindex = FALSE;",
"integer scale = UInt(size);",
"bits(64) offset = SignExtend(imm9, 64);integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"AccType acctype = AccType_UNPRIV;",
"MemOp memop;",
"boolean signed;",
"integer regsize;",
"",
"if opc<1> == '0' then",
" // store or zero-extending load",
" memop = if opc<0> == '1' then MemOp_LOAD else MemOp_STORE;",
" regsize = if size == '11' then 64 else 32;",
" signed = FALSE;",
"else",
" if size == '11' then",
" UnallocatedEncoding();",
" else",
" // sign-extending load",
" memop = MemOp_LOAD;",
" if size == '10' && opc<0> == '1' then UnallocatedEncoding();",
" regsize = if opc<0> == '1' then 32 else 64;",
" signed = TRUE;",
"",
"integer datasize = 8 << scale;"
]
}
],
"name": "LDTRB",
"description": [
"Load Register Byte (unprivileged)"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) data;",
"boolean wb_unknown = FALSE;",
"boolean rt_unknown = FALSE;",
"",
"if memop == MemOp_LOAD && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD);",
" assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed",
" when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if memop == MemOp_STORE && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST);",
" assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_NONE rt_unknown = FALSE; // value stored is original value",
" when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if n == 31 then",
" if memop != MemOp_PREFETCH then CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"if ! postindex then",
" address = address + offset;",
"",
"case memop of",
" when MemOp_STORE",
" if rt_unknown then",
" data = bits(datasize) UNKNOWN;",
" else",
" data = X[t];",
" Mem[address, datasize DIV 8, acctype] = data;",
"",
" when MemOp_LOAD",
" data = Mem[address, datasize DIV 8, acctype];",
" if signed then",
" X[t] = SignExtend(data, regsize);",
" else",
" X[t] = ZeroExtend(data, regsize);",
"",
" when MemOp_PREFETCH",
" Prefetch(address, t<4:0>);",
"",
"if wback then",
" if wb_unknown then",
" address = bits(64) UNKNOWN;",
" elsif postindex then",
" address = address + offset;",
" if n == 31 then",
" SP[] = address;",
" else",
" X[n] = address;"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 opc#2 0 imm9#9 1 0 Rn#5 Rt#5",
"formats": [
{
"condition": null,
"format": "LDTRH <Wt>, [<Xn|SP>{, #<simm>}]"
}
],
"decoder": [
"boolean wback = FALSE;",
"boolean postindex = FALSE;",
"integer scale = UInt(size);",
"bits(64) offset = SignExtend(imm9, 64);integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"AccType acctype = AccType_UNPRIV;",
"MemOp memop;",
"boolean signed;",
"integer regsize;",
"",
"if opc<1> == '0' then",
" // store or zero-extending load",
" memop = if opc<0> == '1' then MemOp_LOAD else MemOp_STORE;",
" regsize = if size == '11' then 64 else 32;",
" signed = FALSE;",
"else",
" if size == '11' then",
" UnallocatedEncoding();",
" else",
" // sign-extending load",
" memop = MemOp_LOAD;",
" if size == '10' && opc<0> == '1' then UnallocatedEncoding();",
" regsize = if opc<0> == '1' then 32 else 64;",
" signed = TRUE;",
"",
"integer datasize = 8 << scale;"
]
}
],
"name": "LDTRH",
"description": [
"Load Register Halfword (unprivileged)"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) data;",
"boolean wb_unknown = FALSE;",
"boolean rt_unknown = FALSE;",
"",
"if memop == MemOp_LOAD && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD);",
" assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed",
" when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if memop == MemOp_STORE && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST);",
" assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_NONE rt_unknown = FALSE; // value stored is original value",
" when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if n == 31 then",
" if memop != MemOp_PREFETCH then CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"if ! postindex then",
" address = address + offset;",
"",
"case memop of",
" when MemOp_STORE",
" if rt_unknown then",
" data = bits(datasize) UNKNOWN;",
" else",
" data = X[t];",
" Mem[address, datasize DIV 8, acctype] = data;",
"",
" when MemOp_LOAD",
" data = Mem[address, datasize DIV 8, acctype];",
" if signed then",
" X[t] = SignExtend(data, regsize);",
" else",
" X[t] = ZeroExtend(data, regsize);",
"",
" when MemOp_PREFETCH",
" Prefetch(address, t<4:0>);",
"",
"if wback then",
" if wb_unknown then",
" address = bits(64) UNKNOWN;",
" elsif postindex then",
" address = address + offset;",
" if n == 31 then",
" SP[] = address;",
" else",
" X[n] = address;"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 opc#2 0 imm9#9 1 0 Rn#5 Rt#5",
"formats": [
{
"condition": "opc == 11",
"format": "LDTRSB <Wt>, [<Xn|SP>{, #<simm>}]"
},
{
"condition": "opc == 10",
"format": "LDTRSB <Xt>, [<Xn|SP>{, #<simm>}]"
}
],
"decoder": [
"boolean wback = FALSE;",
"boolean postindex = FALSE;",
"integer scale = UInt(size);",
"bits(64) offset = SignExtend(imm9, 64);integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"AccType acctype = AccType_UNPRIV;",
"MemOp memop;",
"boolean signed;",
"integer regsize;",
"",
"if opc<1> == '0' then",
" // store or zero-extending load",
" memop = if opc<0> == '1' then MemOp_LOAD else MemOp_STORE;",
" regsize = if size == '11' then 64 else 32;",
" signed = FALSE;",
"else",
" if size == '11' then",
" UnallocatedEncoding();",
" else",
" // sign-extending load",
" memop = MemOp_LOAD;",
" if size == '10' && opc<0> == '1' then UnallocatedEncoding();",
" regsize = if opc<0> == '1' then 32 else 64;",
" signed = TRUE;",
"",
"integer datasize = 8 << scale;"
]
}
],
"name": "LDTRSB",
"description": [
"Load Register Signed Byte (unprivileged)"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) data;",
"boolean wb_unknown = FALSE;",
"boolean rt_unknown = FALSE;",
"",
"if memop == MemOp_LOAD && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD);",
" assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed",
" when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if memop == MemOp_STORE && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST);",
" assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_NONE rt_unknown = FALSE; // value stored is original value",
" when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if n == 31 then",
" if memop != MemOp_PREFETCH then CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"if ! postindex then",
" address = address + offset;",
"",
"case memop of",
" when MemOp_STORE",
" if rt_unknown then",
" data = bits(datasize) UNKNOWN;",
" else",
" data = X[t];",
" Mem[address, datasize DIV 8, acctype] = data;",
"",
" when MemOp_LOAD",
" data = Mem[address, datasize DIV 8, acctype];",
" if signed then",
" X[t] = SignExtend(data, regsize);",
" else",
" X[t] = ZeroExtend(data, regsize);",
"",
" when MemOp_PREFETCH",
" Prefetch(address, t<4:0>);",
"",
"if wback then",
" if wb_unknown then",
" address = bits(64) UNKNOWN;",
" elsif postindex then",
" address = address + offset;",
" if n == 31 then",
" SP[] = address;",
" else",
" X[n] = address;"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 opc#2 0 imm9#9 1 0 Rn#5 Rt#5",
"formats": [
{
"condition": "opc == 11",
"format": "LDTRSH <Wt>, [<Xn|SP>{, #<simm>}]"
},
{
"condition": "opc == 10",
"format": "LDTRSH <Xt>, [<Xn|SP>{, #<simm>}]"
}
],
"decoder": [
"boolean wback = FALSE;",
"boolean postindex = FALSE;",
"integer scale = UInt(size);",
"bits(64) offset = SignExtend(imm9, 64);integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"AccType acctype = AccType_UNPRIV;",
"MemOp memop;",
"boolean signed;",
"integer regsize;",
"",
"if opc<1> == '0' then",
" // store or zero-extending load",
" memop = if opc<0> == '1' then MemOp_LOAD else MemOp_STORE;",
" regsize = if size == '11' then 64 else 32;",
" signed = FALSE;",
"else",
" if size == '11' then",
" UnallocatedEncoding();",
" else",
" // sign-extending load",
" memop = MemOp_LOAD;",
" if size == '10' && opc<0> == '1' then UnallocatedEncoding();",
" regsize = if opc<0> == '1' then 32 else 64;",
" signed = TRUE;",
"",
"integer datasize = 8 << scale;"
]
}
],
"name": "LDTRSH",
"description": [
"Load Register Signed Halfword (unprivileged)"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) data;",
"boolean wb_unknown = FALSE;",
"boolean rt_unknown = FALSE;",
"",
"if memop == MemOp_LOAD && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD);",
" assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed",
" when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if memop == MemOp_STORE && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST);",
" assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_NONE rt_unknown = FALSE; // value stored is original value",
" when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if n == 31 then",
" if memop != MemOp_PREFETCH then CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"if ! postindex then",
" address = address + offset;",
"",
"case memop of",
" when MemOp_STORE",
" if rt_unknown then",
" data = bits(datasize) UNKNOWN;",
" else",
" data = X[t];",
" Mem[address, datasize DIV 8, acctype] = data;",
"",
" when MemOp_LOAD",
" data = Mem[address, datasize DIV 8, acctype];",
" if signed then",
" X[t] = SignExtend(data, regsize);",
" else",
" X[t] = ZeroExtend(data, regsize);",
"",
" when MemOp_PREFETCH",
" Prefetch(address, t<4:0>);",
"",
"if wback then",
" if wb_unknown then",
" address = bits(64) UNKNOWN;",
" elsif postindex then",
" address = address + offset;",
" if n == 31 then",
" SP[] = address;",
" else",
" X[n] = address;"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 opc#2 0 imm9#9 1 0 Rn#5 Rt#5",
"formats": [
{
"condition": null,
"format": "LDTRSW <Xt>, [<Xn|SP>{, #<simm>}]"
}
],
"decoder": [
"boolean wback = FALSE;",
"boolean postindex = FALSE;",
"integer scale = UInt(size);",
"bits(64) offset = SignExtend(imm9, 64);integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"AccType acctype = AccType_UNPRIV;",
"MemOp memop;",
"boolean signed;",
"integer regsize;",
"",
"if opc<1> == '0' then",
" // store or zero-extending load",
" memop = if opc<0> == '1' then MemOp_LOAD else MemOp_STORE;",
" regsize = if size == '11' then 64 else 32;",
" signed = FALSE;",
"else",
" if size == '11' then",
" UnallocatedEncoding();",
" else",
" // sign-extending load",
" memop = MemOp_LOAD;",
" if size == '10' && opc<0> == '1' then UnallocatedEncoding();",
" regsize = if opc<0> == '1' then 32 else 64;",
" signed = TRUE;",
"",
"integer datasize = 8 << scale;"
]
}
],
"name": "LDTRSW",
"description": [
"Load Register Signed Word (unprivileged)"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) value;",
"bits(datasize) data;",
"bits(datasize) result;",
"",
"value = X[s];",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"data = Mem[address, datasize DIV 8, ldacctype];",
"",
"case op of",
" when MemAtomicOp_ADD result = data + value;",
" when MemAtomicOp_BIC result = data AND NOT(value);",
" when MemAtomicOp_EOR result = data EOR value;",
" when MemAtomicOp_ORR result = data OR value;",
" when MemAtomicOp_SMAX result = if SInt(data) > SInt(value) then data else value;",
" when MemAtomicOp_SMIN result = if SInt(data) > SInt(value) then value else data;",
" when MemAtomicOp_UMAX result = if UInt(data) > UInt(value) then data else value;",
" when MemAtomicOp_UMIN result = if UInt(data) > UInt(value) then value else data;",
" when MemAtomicOp_SWP result = value;",
"",
"// All observers in the shareability domain observe the",
"// following load and store atomically.",
"Mem[address, datasize DIV 8, stacctype] = result;",
"",
"X[t] = ZeroExtend(data, regsize);"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 A#1 R#1 1 Rs#5 o3#1 opc#3 0 0 Rn#5 Rt#5",
"formats": [
{
"condition": "size == 10 && A == 1 && R == 0",
"format": "LDUMAXA <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "size == 10 && A == 1 && R == 1",
"format": "LDUMAXAL <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "size == 10 && A == 0 && R == 0 && Rt != 11111",
"format": "LDUMAX <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "size == 10 && A == 0 && R == 1 && Rt != 11111",
"format": "LDUMAXL <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "size == 11 && A == 1 && R == 0",
"format": "LDUMAXA <Xs>, <Xt>, [<Xn|SP>]"
},
{
"condition": "size == 11 && A == 1 && R == 1",
"format": "LDUMAXAL <Xs>, <Xt>, [<Xn|SP>]"
},
{
"condition": "size == 11 && A == 0 && R == 0 && Rt != 11111",
"format": "LDUMAX <Xs>, <Xt>, [<Xn|SP>]"
},
{
"condition": "size == 11 && A == 0 && R == 1 && Rt != 11111",
"format": "LDUMAXL <Xs>, <Xt>, [<Xn|SP>]"
}
],
"decoder": [
"if !HaveAtomicExt() then UnallocatedEncoding();",
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer s = UInt(Rs);",
"",
"integer datasize = 8 << UInt(size);",
"integer regsize = if datasize == 64 then 64 else 32;",
"AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"AccType stacctype = if R == '1' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"MemAtomicOp op;",
"case o3:opc of",
" when '0000' op = MemAtomicOp_ADD;",
" when '0001' op = MemAtomicOp_BIC;",
" when '0010' op = MemAtomicOp_EOR;",
" when '0011' op = MemAtomicOp_ORR;",
" when '0100' op = MemAtomicOp_SMAX;",
" when '0101' op = MemAtomicOp_SMIN;",
" when '0110' op = MemAtomicOp_UMAX;",
" when '0111' op = MemAtomicOp_UMIN;",
" when '1000' op = MemAtomicOp_SWP;",
" otherwise UnallocatedEncoding();"
]
}
],
"name": "LDUMAX, LDUMAXA, LDUMAXAL, LDUMAXL",
"description": [
"Atomic unsigned maximum on word or doubleword in memory"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) value;",
"bits(datasize) data;",
"bits(datasize) result;",
"",
"value = X[s];",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"data = Mem[address, datasize DIV 8, ldacctype];",
"",
"case op of",
" when MemAtomicOp_ADD result = data + value;",
" when MemAtomicOp_BIC result = data AND NOT(value);",
" when MemAtomicOp_EOR result = data EOR value;",
" when MemAtomicOp_ORR result = data OR value;",
" when MemAtomicOp_SMAX result = if SInt(data) > SInt(value) then data else value;",
" when MemAtomicOp_SMIN result = if SInt(data) > SInt(value) then value else data;",
" when MemAtomicOp_UMAX result = if UInt(data) > UInt(value) then data else value;",
" when MemAtomicOp_UMIN result = if UInt(data) > UInt(value) then value else data;",
" when MemAtomicOp_SWP result = value;",
"",
"// All observers in the shareability domain observe the",
"// following load and store atomically.",
"Mem[address, datasize DIV 8, stacctype] = result;",
"",
"X[t] = ZeroExtend(data, regsize);"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 A#1 R#1 1 Rs#5 o3#1 opc#3 0 0 Rn#5 Rt#5",
"formats": [
{
"condition": "A == 1 && R == 0",
"format": "LDUMAXAB <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 1 && R == 1",
"format": "LDUMAXALB <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 0 && R == 0 && Rt != 11111",
"format": "LDUMAXB <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 0 && R == 1 && Rt != 11111",
"format": "LDUMAXLB <Ws>, <Wt>, [<Xn|SP>]"
}
],
"decoder": [
"if !HaveAtomicExt() then UnallocatedEncoding();",
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer s = UInt(Rs);",
"",
"integer datasize = 8 << UInt(size);",
"integer regsize = if datasize == 64 then 64 else 32;",
"AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"AccType stacctype = if R == '1' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"MemAtomicOp op;",
"case o3:opc of",
" when '0000' op = MemAtomicOp_ADD;",
" when '0001' op = MemAtomicOp_BIC;",
" when '0010' op = MemAtomicOp_EOR;",
" when '0011' op = MemAtomicOp_ORR;",
" when '0100' op = MemAtomicOp_SMAX;",
" when '0101' op = MemAtomicOp_SMIN;",
" when '0110' op = MemAtomicOp_UMAX;",
" when '0111' op = MemAtomicOp_UMIN;",
" when '1000' op = MemAtomicOp_SWP;",
" otherwise UnallocatedEncoding();"
]
}
],
"name": "LDUMAXB, LDUMAXAB, LDUMAXALB, LDUMAXLB",
"description": [
"Atomic unsigned maximum on byte in memory"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) value;",
"bits(datasize) data;",
"bits(datasize) result;",
"",
"value = X[s];",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"data = Mem[address, datasize DIV 8, ldacctype];",
"",
"case op of",
" when MemAtomicOp_ADD result = data + value;",
" when MemAtomicOp_BIC result = data AND NOT(value);",
" when MemAtomicOp_EOR result = data EOR value;",
" when MemAtomicOp_ORR result = data OR value;",
" when MemAtomicOp_SMAX result = if SInt(data) > SInt(value) then data else value;",
" when MemAtomicOp_SMIN result = if SInt(data) > SInt(value) then value else data;",
" when MemAtomicOp_UMAX result = if UInt(data) > UInt(value) then data else value;",
" when MemAtomicOp_UMIN result = if UInt(data) > UInt(value) then value else data;",
" when MemAtomicOp_SWP result = value;",
"",
"// All observers in the shareability domain observe the",
"// following load and store atomically.",
"Mem[address, datasize DIV 8, stacctype] = result;",
"",
"X[t] = ZeroExtend(data, regsize);"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 A#1 R#1 1 Rs#5 o3#1 opc#3 0 0 Rn#5 Rt#5",
"formats": [
{
"condition": "A == 1 && R == 0",
"format": "LDUMAXAH <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 1 && R == 1",
"format": "LDUMAXALH <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 0 && R == 0 && Rt != 11111",
"format": "LDUMAXH <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 0 && R == 1 && Rt != 11111",
"format": "LDUMAXLH <Ws>, <Wt>, [<Xn|SP>]"
}
],
"decoder": [
"if !HaveAtomicExt() then UnallocatedEncoding();",
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer s = UInt(Rs);",
"",
"integer datasize = 8 << UInt(size);",
"integer regsize = if datasize == 64 then 64 else 32;",
"AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"AccType stacctype = if R == '1' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"MemAtomicOp op;",
"case o3:opc of",
" when '0000' op = MemAtomicOp_ADD;",
" when '0001' op = MemAtomicOp_BIC;",
" when '0010' op = MemAtomicOp_EOR;",
" when '0011' op = MemAtomicOp_ORR;",
" when '0100' op = MemAtomicOp_SMAX;",
" when '0101' op = MemAtomicOp_SMIN;",
" when '0110' op = MemAtomicOp_UMAX;",
" when '0111' op = MemAtomicOp_UMIN;",
" when '1000' op = MemAtomicOp_SWP;",
" otherwise UnallocatedEncoding();"
]
}
],
"name": "LDUMAXH, LDUMAXAH, LDUMAXALH, LDUMAXLH",
"description": [
"Atomic unsigned maximum on halfword in memory"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) value;",
"bits(datasize) data;",
"bits(datasize) result;",
"",
"value = X[s];",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"data = Mem[address, datasize DIV 8, ldacctype];",
"",
"case op of",
" when MemAtomicOp_ADD result = data + value;",
" when MemAtomicOp_BIC result = data AND NOT(value);",
" when MemAtomicOp_EOR result = data EOR value;",
" when MemAtomicOp_ORR result = data OR value;",
" when MemAtomicOp_SMAX result = if SInt(data) > SInt(value) then data else value;",
" when MemAtomicOp_SMIN result = if SInt(data) > SInt(value) then value else data;",
" when MemAtomicOp_UMAX result = if UInt(data) > UInt(value) then data else value;",
" when MemAtomicOp_UMIN result = if UInt(data) > UInt(value) then value else data;",
" when MemAtomicOp_SWP result = value;",
"",
"// All observers in the shareability domain observe the",
"// following load and store atomically.",
"Mem[address, datasize DIV 8, stacctype] = result;",
"",
"X[t] = ZeroExtend(data, regsize);"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 A#1 R#1 1 Rs#5 o3#1 opc#3 0 0 Rn#5 Rt#5",
"formats": [
{
"condition": "size == 10 && A == 1 && R == 0",
"format": "LDUMINA <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "size == 10 && A == 1 && R == 1",
"format": "LDUMINAL <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "size == 10 && A == 0 && R == 0 && Rt != 11111",
"format": "LDUMIN <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "size == 10 && A == 0 && R == 1 && Rt != 11111",
"format": "LDUMINL <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "size == 11 && A == 1 && R == 0",
"format": "LDUMINA <Xs>, <Xt>, [<Xn|SP>]"
},
{
"condition": "size == 11 && A == 1 && R == 1",
"format": "LDUMINAL <Xs>, <Xt>, [<Xn|SP>]"
},
{
"condition": "size == 11 && A == 0 && R == 0 && Rt != 11111",
"format": "LDUMIN <Xs>, <Xt>, [<Xn|SP>]"
},
{
"condition": "size == 11 && A == 0 && R == 1 && Rt != 11111",
"format": "LDUMINL <Xs>, <Xt>, [<Xn|SP>]"
}
],
"decoder": [
"if !HaveAtomicExt() then UnallocatedEncoding();",
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer s = UInt(Rs);",
"",
"integer datasize = 8 << UInt(size);",
"integer regsize = if datasize == 64 then 64 else 32;",
"AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"AccType stacctype = if R == '1' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"MemAtomicOp op;",
"case o3:opc of",
" when '0000' op = MemAtomicOp_ADD;",
" when '0001' op = MemAtomicOp_BIC;",
" when '0010' op = MemAtomicOp_EOR;",
" when '0011' op = MemAtomicOp_ORR;",
" when '0100' op = MemAtomicOp_SMAX;",
" when '0101' op = MemAtomicOp_SMIN;",
" when '0110' op = MemAtomicOp_UMAX;",
" when '0111' op = MemAtomicOp_UMIN;",
" when '1000' op = MemAtomicOp_SWP;",
" otherwise UnallocatedEncoding();"
]
}
],
"name": "LDUMIN, LDUMINA, LDUMINAL, LDUMINL",
"description": [
"Atomic unsigned minimum on word or doubleword in memory"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) value;",
"bits(datasize) data;",
"bits(datasize) result;",
"",
"value = X[s];",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"data = Mem[address, datasize DIV 8, ldacctype];",
"",
"case op of",
" when MemAtomicOp_ADD result = data + value;",
" when MemAtomicOp_BIC result = data AND NOT(value);",
" when MemAtomicOp_EOR result = data EOR value;",
" when MemAtomicOp_ORR result = data OR value;",
" when MemAtomicOp_SMAX result = if SInt(data) > SInt(value) then data else value;",
" when MemAtomicOp_SMIN result = if SInt(data) > SInt(value) then value else data;",
" when MemAtomicOp_UMAX result = if UInt(data) > UInt(value) then data else value;",
" when MemAtomicOp_UMIN result = if UInt(data) > UInt(value) then value else data;",
" when MemAtomicOp_SWP result = value;",
"",
"// All observers in the shareability domain observe the",
"// following load and store atomically.",
"Mem[address, datasize DIV 8, stacctype] = result;",
"",
"X[t] = ZeroExtend(data, regsize);"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 A#1 R#1 1 Rs#5 o3#1 opc#3 0 0 Rn#5 Rt#5",
"formats": [
{
"condition": "A == 1 && R == 0",
"format": "LDUMINAB <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 1 && R == 1",
"format": "LDUMINALB <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 0 && R == 0 && Rt != 11111",
"format": "LDUMINB <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 0 && R == 1 && Rt != 11111",
"format": "LDUMINLB <Ws>, <Wt>, [<Xn|SP>]"
}
],
"decoder": [
"if !HaveAtomicExt() then UnallocatedEncoding();",
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer s = UInt(Rs);",
"",
"integer datasize = 8 << UInt(size);",
"integer regsize = if datasize == 64 then 64 else 32;",
"AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"AccType stacctype = if R == '1' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"MemAtomicOp op;",
"case o3:opc of",
" when '0000' op = MemAtomicOp_ADD;",
" when '0001' op = MemAtomicOp_BIC;",
" when '0010' op = MemAtomicOp_EOR;",
" when '0011' op = MemAtomicOp_ORR;",
" when '0100' op = MemAtomicOp_SMAX;",
" when '0101' op = MemAtomicOp_SMIN;",
" when '0110' op = MemAtomicOp_UMAX;",
" when '0111' op = MemAtomicOp_UMIN;",
" when '1000' op = MemAtomicOp_SWP;",
" otherwise UnallocatedEncoding();"
]
}
],
"name": "LDUMINB, LDUMINAB, LDUMINALB, LDUMINLB",
"description": [
"Atomic unsigned minimum on byte in memory"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) value;",
"bits(datasize) data;",
"bits(datasize) result;",
"",
"value = X[s];",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"data = Mem[address, datasize DIV 8, ldacctype];",
"",
"case op of",
" when MemAtomicOp_ADD result = data + value;",
" when MemAtomicOp_BIC result = data AND NOT(value);",
" when MemAtomicOp_EOR result = data EOR value;",
" when MemAtomicOp_ORR result = data OR value;",
" when MemAtomicOp_SMAX result = if SInt(data) > SInt(value) then data else value;",
" when MemAtomicOp_SMIN result = if SInt(data) > SInt(value) then value else data;",
" when MemAtomicOp_UMAX result = if UInt(data) > UInt(value) then data else value;",
" when MemAtomicOp_UMIN result = if UInt(data) > UInt(value) then value else data;",
" when MemAtomicOp_SWP result = value;",
"",
"// All observers in the shareability domain observe the",
"// following load and store atomically.",
"Mem[address, datasize DIV 8, stacctype] = result;",
"",
"X[t] = ZeroExtend(data, regsize);"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 A#1 R#1 1 Rs#5 o3#1 opc#3 0 0 Rn#5 Rt#5",
"formats": [
{
"condition": "A == 1 && R == 0",
"format": "LDUMINAH <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 1 && R == 1",
"format": "LDUMINALH <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 0 && R == 0 && Rt != 11111",
"format": "LDUMINH <Ws>, <Wt>, [<Xn|SP>]"
},
{
"condition": "A == 0 && R == 1 && Rt != 11111",
"format": "LDUMINLH <Ws>, <Wt>, [<Xn|SP>]"
}
],
"decoder": [
"if !HaveAtomicExt() then UnallocatedEncoding();",
"integer t = UInt(Rt);",
"integer n = UInt(Rn);",
"integer s = UInt(Rs);",
"",
"integer datasize = 8 << UInt(size);",
"integer regsize = if datasize == 64 then 64 else 32;",
"AccType ldacctype = if A == '1' && Rt != '11111' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"AccType stacctype = if R == '1' then AccType_ORDEREDRW else AccType_ATOMICRW;",
"MemAtomicOp op;",
"case o3:opc of",
" when '0000' op = MemAtomicOp_ADD;",
" when '0001' op = MemAtomicOp_BIC;",
" when '0010' op = MemAtomicOp_EOR;",
" when '0011' op = MemAtomicOp_ORR;",
" when '0100' op = MemAtomicOp_SMAX;",
" when '0101' op = MemAtomicOp_SMIN;",
" when '0110' op = MemAtomicOp_UMAX;",
" when '0111' op = MemAtomicOp_UMIN;",
" when '1000' op = MemAtomicOp_SWP;",
" otherwise UnallocatedEncoding();"
]
}
],
"name": "LDUMINH, LDUMINAH, LDUMINALH, LDUMINLH",
"description": [
"Atomic unsigned minimum on halfword in memory"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"",
"bits(64) address;",
"bits(datasize) data;",
"",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"if ! postindex then",
" address = address + offset;",
"",
"case memop of",
" when MemOp_STORE",
" data = V[t];",
" Mem[address, datasize DIV 8, acctype] = data;",
"",
" when MemOp_LOAD",
" data = Mem[address, datasize DIV 8, acctype];",
" V[t] = data;",
"",
"if wback then",
" if postindex then",
" address = address + offset;",
" if n == 31 then",
" SP[] = address;",
" else",
" X[n] = address;"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 opc#2 0 imm9#9 0 0 Rn#5 Rt#5",
"formats": [
{
"condition": "size == 00 && opc == 01",
"format": "LDUR <Bt>, [<Xn|SP>{, #<simm>}]"
},
{
"condition": "size == 01 && opc == 01",
"format": "LDUR <Ht>, [<Xn|SP>{, #<simm>}]"
},
{
"condition": "size == 10 && opc == 01",
"format": "LDUR <St>, [<Xn|SP>{, #<simm>}]"
},
{
"condition": "size == 11 && opc == 01",
"format": "LDUR <Dt>, [<Xn|SP>{, #<simm>}]"
},
{
"condition": "size == 00 && opc == 11",
"format": "LDUR <Qt>, [<Xn|SP>{, #<simm>}]"
}
],
"decoder": [
"boolean wback = FALSE;",
"boolean postindex = FALSE;",
"integer scale = UInt(opc<1>:size);",
"if scale > 4 then UnallocatedEncoding();",
"bits(64) offset = SignExtend(imm9, 64);integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"AccType acctype = AccType_VEC;",
"MemOp memop = if opc<0> == '1' then MemOp_LOAD else MemOp_STORE;",
"integer datasize = 8 << scale;"
]
}
],
"name": "LDUR (SIMD&FP)",
"description": [
"Load SIMD&FP Register (unscaled offset)"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) data;",
"boolean wb_unknown = FALSE;",
"boolean rt_unknown = FALSE;",
"",
"if memop == MemOp_LOAD && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD);",
" assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed",
" when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if memop == MemOp_STORE && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST);",
" assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_NONE rt_unknown = FALSE; // value stored is original value",
" when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if n == 31 then",
" if memop != MemOp_PREFETCH then CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"if ! postindex then",
" address = address + offset;",
"",
"case memop of",
" when MemOp_STORE",
" if rt_unknown then",
" data = bits(datasize) UNKNOWN;",
" else",
" data = X[t];",
" Mem[address, datasize DIV 8, acctype] = data;",
"",
" when MemOp_LOAD",
" data = Mem[address, datasize DIV 8, acctype];",
" if signed then",
" X[t] = SignExtend(data, regsize);",
" else",
" X[t] = ZeroExtend(data, regsize);",
"",
" when MemOp_PREFETCH",
" Prefetch(address, t<4:0>);",
"",
"if wback then",
" if wb_unknown then",
" address = bits(64) UNKNOWN;",
" elsif postindex then",
" address = address + offset;",
" if n == 31 then",
" SP[] = address;",
" else",
" X[n] = address;"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 opc#2 0 imm9#9 0 0 Rn#5 Rt#5",
"formats": [
{
"condition": "size == 10",
"format": "LDUR <Wt>, [<Xn|SP>{, #<simm>}]"
},
{
"condition": "size == 11",
"format": "LDUR <Xt>, [<Xn|SP>{, #<simm>}]"
}
],
"decoder": [
"boolean wback = FALSE;",
"boolean postindex = FALSE;",
"integer scale = UInt(size);",
"bits(64) offset = SignExtend(imm9, 64);integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"AccType acctype = AccType_NORMAL;",
"MemOp memop;",
"boolean signed;",
"integer regsize;",
"",
"if opc<1> == '0' then",
" // store or zero-extending load",
" memop = if opc<0> == '1' then MemOp_LOAD else MemOp_STORE;",
" regsize = if size == '11' then 64 else 32;",
" signed = FALSE;",
"else",
" if size == '11' then",
" memop = MemOp_PREFETCH;",
" if opc<0> == '1' then UnallocatedEncoding();",
" else",
" // sign-extending load",
" memop = MemOp_LOAD;",
" if size == '10' && opc<0> == '1' then UnallocatedEncoding();",
" regsize = if opc<0> == '1' then 32 else 64;",
" signed = TRUE;",
"",
"integer datasize = 8 << scale;"
]
}
],
"name": "LDUR",
"description": [
"Load Register (unscaled)"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) data;",
"boolean wb_unknown = FALSE;",
"boolean rt_unknown = FALSE;",
"",
"if memop == MemOp_LOAD && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD);",
" assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed",
" when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if memop == MemOp_STORE && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST);",
" assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_NONE rt_unknown = FALSE; // value stored is original value",
" when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if n == 31 then",
" if memop != MemOp_PREFETCH then CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"if ! postindex then",
" address = address + offset;",
"",
"case memop of",
" when MemOp_STORE",
" if rt_unknown then",
" data = bits(datasize) UNKNOWN;",
" else",
" data = X[t];",
" Mem[address, datasize DIV 8, acctype] = data;",
"",
" when MemOp_LOAD",
" data = Mem[address, datasize DIV 8, acctype];",
" if signed then",
" X[t] = SignExtend(data, regsize);",
" else",
" X[t] = ZeroExtend(data, regsize);",
"",
" when MemOp_PREFETCH",
" Prefetch(address, t<4:0>);",
"",
"if wback then",
" if wb_unknown then",
" address = bits(64) UNKNOWN;",
" elsif postindex then",
" address = address + offset;",
" if n == 31 then",
" SP[] = address;",
" else",
" X[n] = address;"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 opc#2 0 imm9#9 0 0 Rn#5 Rt#5",
"formats": [
{
"condition": null,
"format": "LDURB <Wt>, [<Xn|SP>{, #<simm>}]"
}
],
"decoder": [
"boolean wback = FALSE;",
"boolean postindex = FALSE;",
"integer scale = UInt(size);",
"bits(64) offset = SignExtend(imm9, 64);integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"AccType acctype = AccType_NORMAL;",
"MemOp memop;",
"boolean signed;",
"integer regsize;",
"",
"if opc<1> == '0' then",
" // store or zero-extending load",
" memop = if opc<0> == '1' then MemOp_LOAD else MemOp_STORE;",
" regsize = if size == '11' then 64 else 32;",
" signed = FALSE;",
"else",
" if size == '11' then",
" memop = MemOp_PREFETCH;",
" if opc<0> == '1' then UnallocatedEncoding();",
" else",
" // sign-extending load",
" memop = MemOp_LOAD;",
" if size == '10' && opc<0> == '1' then UnallocatedEncoding();",
" regsize = if opc<0> == '1' then 32 else 64;",
" signed = TRUE;",
"",
"integer datasize = 8 << scale;"
]
}
],
"name": "LDURB",
"description": [
"Load Register Byte (unscaled)"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) data;",
"boolean wb_unknown = FALSE;",
"boolean rt_unknown = FALSE;",
"",
"if memop == MemOp_LOAD && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD);",
" assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed",
" when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if memop == MemOp_STORE && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST);",
" assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_NONE rt_unknown = FALSE; // value stored is original value",
" when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if n == 31 then",
" if memop != MemOp_PREFETCH then CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"if ! postindex then",
" address = address + offset;",
"",
"case memop of",
" when MemOp_STORE",
" if rt_unknown then",
" data = bits(datasize) UNKNOWN;",
" else",
" data = X[t];",
" Mem[address, datasize DIV 8, acctype] = data;",
"",
" when MemOp_LOAD",
" data = Mem[address, datasize DIV 8, acctype];",
" if signed then",
" X[t] = SignExtend(data, regsize);",
" else",
" X[t] = ZeroExtend(data, regsize);",
"",
" when MemOp_PREFETCH",
" Prefetch(address, t<4:0>);",
"",
"if wback then",
" if wb_unknown then",
" address = bits(64) UNKNOWN;",
" elsif postindex then",
" address = address + offset;",
" if n == 31 then",
" SP[] = address;",
" else",
" X[n] = address;"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 opc#2 0 imm9#9 0 0 Rn#5 Rt#5",
"formats": [
{
"condition": null,
"format": "LDURH <Wt>, [<Xn|SP>{, #<simm>}]"
}
],
"decoder": [
"boolean wback = FALSE;",
"boolean postindex = FALSE;",
"integer scale = UInt(size);",
"bits(64) offset = SignExtend(imm9, 64);integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"AccType acctype = AccType_NORMAL;",
"MemOp memop;",
"boolean signed;",
"integer regsize;",
"",
"if opc<1> == '0' then",
" // store or zero-extending load",
" memop = if opc<0> == '1' then MemOp_LOAD else MemOp_STORE;",
" regsize = if size == '11' then 64 else 32;",
" signed = FALSE;",
"else",
" if size == '11' then",
" memop = MemOp_PREFETCH;",
" if opc<0> == '1' then UnallocatedEncoding();",
" else",
" // sign-extending load",
" memop = MemOp_LOAD;",
" if size == '10' && opc<0> == '1' then UnallocatedEncoding();",
" regsize = if opc<0> == '1' then 32 else 64;",
" signed = TRUE;",
"",
"integer datasize = 8 << scale;"
]
}
],
"name": "LDURH",
"description": [
"Load Register Halfword (unscaled)"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) data;",
"boolean wb_unknown = FALSE;",
"boolean rt_unknown = FALSE;",
"",
"if memop == MemOp_LOAD && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD);",
" assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed",
" when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if memop == MemOp_STORE && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST);",
" assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_NONE rt_unknown = FALSE; // value stored is original value",
" when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if n == 31 then",
" if memop != MemOp_PREFETCH then CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"if ! postindex then",
" address = address + offset;",
"",
"case memop of",
" when MemOp_STORE",
" if rt_unknown then",
" data = bits(datasize) UNKNOWN;",
" else",
" data = X[t];",
" Mem[address, datasize DIV 8, acctype] = data;",
"",
" when MemOp_LOAD",
" data = Mem[address, datasize DIV 8, acctype];",
" if signed then",
" X[t] = SignExtend(data, regsize);",
" else",
" X[t] = ZeroExtend(data, regsize);",
"",
" when MemOp_PREFETCH",
" Prefetch(address, t<4:0>);",
"",
"if wback then",
" if wb_unknown then",
" address = bits(64) UNKNOWN;",
" elsif postindex then",
" address = address + offset;",
" if n == 31 then",
" SP[] = address;",
" else",
" X[n] = address;"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 opc#2 0 imm9#9 0 0 Rn#5 Rt#5",
"formats": [
{
"condition": "opc == 11",
"format": "LDURSB <Wt>, [<Xn|SP>{, #<simm>}]"
},
{
"condition": "opc == 10",
"format": "LDURSB <Xt>, [<Xn|SP>{, #<simm>}]"
}
],
"decoder": [
"boolean wback = FALSE;",
"boolean postindex = FALSE;",
"integer scale = UInt(size);",
"bits(64) offset = SignExtend(imm9, 64);integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"AccType acctype = AccType_NORMAL;",
"MemOp memop;",
"boolean signed;",
"integer regsize;",
"",
"if opc<1> == '0' then",
" // store or zero-extending load",
" memop = if opc<0> == '1' then MemOp_LOAD else MemOp_STORE;",
" regsize = if size == '11' then 64 else 32;",
" signed = FALSE;",
"else",
" if size == '11' then",
" memop = MemOp_PREFETCH;",
" if opc<0> == '1' then UnallocatedEncoding();",
" else",
" // sign-extending load",
" memop = MemOp_LOAD;",
" if size == '10' && opc<0> == '1' then UnallocatedEncoding();",
" regsize = if opc<0> == '1' then 32 else 64;",
" signed = TRUE;",
"",
"integer datasize = 8 << scale;"
]
}
],
"name": "LDURSB",
"description": [
"Load Register Signed Byte (unscaled)"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) data;",
"boolean wb_unknown = FALSE;",
"boolean rt_unknown = FALSE;",
"",
"if memop == MemOp_LOAD && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD);",
" assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed",
" when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if memop == MemOp_STORE && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST);",
" assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_NONE rt_unknown = FALSE; // value stored is original value",
" when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if n == 31 then",
" if memop != MemOp_PREFETCH then CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"if ! postindex then",
" address = address + offset;",
"",
"case memop of",
" when MemOp_STORE",
" if rt_unknown then",
" data = bits(datasize) UNKNOWN;",
" else",
" data = X[t];",
" Mem[address, datasize DIV 8, acctype] = data;",
"",
" when MemOp_LOAD",
" data = Mem[address, datasize DIV 8, acctype];",
" if signed then",
" X[t] = SignExtend(data, regsize);",
" else",
" X[t] = ZeroExtend(data, regsize);",
"",
" when MemOp_PREFETCH",
" Prefetch(address, t<4:0>);",
"",
"if wback then",
" if wb_unknown then",
" address = bits(64) UNKNOWN;",
" elsif postindex then",
" address = address + offset;",
" if n == 31 then",
" SP[] = address;",
" else",
" X[n] = address;"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 opc#2 0 imm9#9 0 0 Rn#5 Rt#5",
"formats": [
{
"condition": "opc == 11",
"format": "LDURSH <Wt>, [<Xn|SP>{, #<simm>}]"
},
{
"condition": "opc == 10",
"format": "LDURSH <Xt>, [<Xn|SP>{, #<simm>}]"
}
],
"decoder": [
"boolean wback = FALSE;",
"boolean postindex = FALSE;",
"integer scale = UInt(size);",
"bits(64) offset = SignExtend(imm9, 64);integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"AccType acctype = AccType_NORMAL;",
"MemOp memop;",
"boolean signed;",
"integer regsize;",
"",
"if opc<1> == '0' then",
" // store or zero-extending load",
" memop = if opc<0> == '1' then MemOp_LOAD else MemOp_STORE;",
" regsize = if size == '11' then 64 else 32;",
" signed = FALSE;",
"else",
" if size == '11' then",
" memop = MemOp_PREFETCH;",
" if opc<0> == '1' then UnallocatedEncoding();",
" else",
" // sign-extending load",
" memop = MemOp_LOAD;",
" if size == '10' && opc<0> == '1' then UnallocatedEncoding();",
" regsize = if opc<0> == '1' then 32 else 64;",
" signed = TRUE;",
"",
"integer datasize = 8 << scale;"
]
}
],
"name": "LDURSH",
"description": [
"Load Register Signed Halfword (unscaled)"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) data;",
"boolean wb_unknown = FALSE;",
"boolean rt_unknown = FALSE;",
"",
"if memop == MemOp_LOAD && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPLD);",
" assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_WBSUPPRESS wback = FALSE; // writeback is suppressed",
" when Constraint_UNKNOWN wb_unknown = TRUE; // writeback is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if memop == MemOp_STORE && wback && n == t && n != 31 then",
" c = ConstrainUnpredictable(Unpredictable_WBOVERLAPST);",
" assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_NONE rt_unknown = FALSE; // value stored is original value",
" when Constraint_UNKNOWN rt_unknown = TRUE; // value stored is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if n == 31 then",
" if memop != MemOp_PREFETCH then CheckSPAlignment();",
" address = SP[];",
"else",
" address = X[n];",
"",
"if ! postindex then",
" address = address + offset;",
"",
"case memop of",
" when MemOp_STORE",
" if rt_unknown then",
" data = bits(datasize) UNKNOWN;",
" else",
" data = X[t];",
" Mem[address, datasize DIV 8, acctype] = data;",
"",
" when MemOp_LOAD",
" data = Mem[address, datasize DIV 8, acctype];",
" if signed then",
" X[t] = SignExtend(data, regsize);",
" else",
" X[t] = ZeroExtend(data, regsize);",
"",
" when MemOp_PREFETCH",
" Prefetch(address, t<4:0>);",
"",
"if wback then",
" if wb_unknown then",
" address = bits(64) UNKNOWN;",
" elsif postindex then",
" address = address + offset;",
" if n == 31 then",
" SP[] = address;",
" else",
" X[n] = address;"
],
"variants": [
{
"pattern": "size#2 1 1 1 V#1 0 0 opc#2 0 imm9#9 0 0 Rn#5 Rt#5",
"formats": [
{
"condition": null,
"format": "LDURSW <Xt>, [<Xn|SP>{, #<simm>}]"
}
],
"decoder": [
"boolean wback = FALSE;",
"boolean postindex = FALSE;",
"integer scale = UInt(size);",
"bits(64) offset = SignExtend(imm9, 64);integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"AccType acctype = AccType_NORMAL;",
"MemOp memop;",
"boolean signed;",
"integer regsize;",
"",
"if opc<1> == '0' then",
" // store or zero-extending load",
" memop = if opc<0> == '1' then MemOp_LOAD else MemOp_STORE;",
" regsize = if size == '11' then 64 else 32;",
" signed = FALSE;",
"else",
" if size == '11' then",
" memop = MemOp_PREFETCH;",
" if opc<0> == '1' then UnallocatedEncoding();",
" else",
" // sign-extending load",
" memop = MemOp_LOAD;",
" if size == '10' && opc<0> == '1' then UnallocatedEncoding();",
" regsize = if opc<0> == '1' then 32 else 64;",
" signed = TRUE;",
"",
"integer datasize = 8 << scale;"
]
}
],
"name": "LDURSW",
"description": [
"Load Register Signed Word (unscaled)"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) data;",
"constant integer dbytes = datasize DIV 8;",
"boolean rt_unknown = FALSE;",
"boolean rn_unknown = FALSE;",
"",
"if memop == MemOp_LOAD && pair && t == t2 then",
" Constraint c = ConstrainUnpredictable(Unpredictable_LDPOVERLAP);",
" assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_UNKNOWN rt_unknown = TRUE; // result is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if memop == MemOp_STORE then",
" if s == t || (pair && s == t2) then",
" Constraint c = ConstrainUnpredictable(Unpredictable_DATAOVERLAP);",
" assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_UNKNOWN rt_unknown = TRUE; // store UNKNOWN value",
" when Constraint_NONE rt_unknown = FALSE; // store original value",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
" if s == n && n != 31 then",
" Constraint c = ConstrainUnpredictable(Unpredictable_BASEOVERLAP);",
" assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_UNKNOWN rn_unknown = TRUE; // address is UNKNOWN",
" when Constraint_NONE rn_unknown = FALSE; // address is original base",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"elsif rn_unknown then",
" address = bits(64) UNKNOWN;",
"else",
" address = X[n];",
"",
"case memop of",
" when MemOp_STORE",
" if rt_unknown then",
" data = bits(datasize) UNKNOWN;",
" elsif pair then",
" bits(datasize DIV 2) el1 = X[t];",
" bits(datasize DIV 2) el2 = X[t2];",
" data = if BigEndian() then el1 : el2 else el2 : el1;",
" else",
" data = X[t];",
"",
" bit status = '1';",
" // Check whether the Exclusive Monitors are set to include the",
" // physical memory locations corresponding to virtual address",
" // range [address, address+dbytes-1].",
" if AArch64.ExclusiveMonitorsPass(address, dbytes) then",
" // This atomic write will be rejected if it does not refer",
" // to the same physical locations after address translation.",
" Mem[address, dbytes, acctype] = data;",
" status = ExclusiveMonitorsStatus();",
" X[s] = ZeroExtend(status, 32);",
"",
" when MemOp_LOAD",
" // Tell the Exclusive Monitors to record a sequence of one or more atomic",
" // memory reads from virtual address range [address, address+dbytes-1].",
" // The Exclusive Monitor will only be set if all the reads are from the",
" // same dbytes-aligned physical address, to allow for the possibility of",
" // an atomicity break if the translation is changed between reads.",
" AArch64.SetExclusiveMonitors(address, dbytes);",
"",
" if pair then",
" if rt_unknown then",
" // ConstrainedUNPREDICTABLE case",
" X[t] = bits(datasize) UNKNOWN;",
" elsif elsize == 32 then",
" // 32-bit load exclusive pair (atomic)",
" data = Mem[address, dbytes, acctype];",
" if BigEndian() then",
" X[t] = data;",
" X[t2] = data;",
" else",
" X[t] = data;",
" X[t2] = data;",
" else // elsize == 64",
" // 64-bit load exclusive pair (not atomic),",
" // but must be 128-bit aligned",
" if address != Align(address, dbytes) then",
" iswrite = FALSE;",
" secondstage = FALSE;",
" AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage));",
" X[t] = Mem[address + 0, 8, acctype];",
" X[t2] = Mem[address + 8, 8, acctype];",
" else",
" data = Mem[address, dbytes, acctype];",
" X[t] = ZeroExtend(data, regsize);"
],
"variants": [
{
"pattern": "1 sz#1 0 0 1 0 0 0 o2#1 L#1 o1#1 Rs#5 o0#1 Rt2#5 Rn#5 Rt#5",
"formats": [
{
"condition": "sz == 0",
"format": "LDXP <Wt1>, <Wt2>, [<Xn|SP>{,#0}]"
},
{
"condition": "sz == 1",
"format": "LDXP <Xt1>, <Xt2>, [<Xn|SP>{,#0}]"
}
],
"decoder": [
"integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"integer t2 = UInt(Rt2); // ignored by load/store single register",
"integer s = UInt(Rs); // ignored by all loads and store-release",
"",
"AccType acctype = if o0 == '1' then AccType_ORDERED else AccType_ATOMIC;",
"boolean pair = TRUE;",
"MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"integer elsize = 32 << UInt(sz);",
"integer regsize = if elsize == 64 then 64 else 32;",
"integer datasize = if pair then elsize * 2 else elsize;"
]
}
],
"name": "LDXP",
"description": [
"Load Exclusive Pair of Registers"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) data;",
"constant integer dbytes = datasize DIV 8;",
"boolean rt_unknown = FALSE;",
"boolean rn_unknown = FALSE;",
"",
"if memop == MemOp_LOAD && pair && t == t2 then",
" Constraint c = ConstrainUnpredictable(Unpredictable_LDPOVERLAP);",
" assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_UNKNOWN rt_unknown = TRUE; // result is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if memop == MemOp_STORE then",
" if s == t || (pair && s == t2) then",
" Constraint c = ConstrainUnpredictable(Unpredictable_DATAOVERLAP);",
" assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_UNKNOWN rt_unknown = TRUE; // store UNKNOWN value",
" when Constraint_NONE rt_unknown = FALSE; // store original value",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
" if s == n && n != 31 then",
" Constraint c = ConstrainUnpredictable(Unpredictable_BASEOVERLAP);",
" assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_UNKNOWN rn_unknown = TRUE; // address is UNKNOWN",
" when Constraint_NONE rn_unknown = FALSE; // address is original base",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"elsif rn_unknown then",
" address = bits(64) UNKNOWN;",
"else",
" address = X[n];",
"",
"case memop of",
" when MemOp_STORE",
" if rt_unknown then",
" data = bits(datasize) UNKNOWN;",
" elsif pair then",
" bits(datasize DIV 2) el1 = X[t];",
" bits(datasize DIV 2) el2 = X[t2];",
" data = if BigEndian() then el1 : el2 else el2 : el1;",
" else",
" data = X[t];",
"",
" bit status = '1';",
" // Check whether the Exclusive Monitors are set to include the",
" // physical memory locations corresponding to virtual address",
" // range [address, address+dbytes-1].",
" if AArch64.ExclusiveMonitorsPass(address, dbytes) then",
" // This atomic write will be rejected if it does not refer",
" // to the same physical locations after address translation.",
" Mem[address, dbytes, acctype] = data;",
" status = ExclusiveMonitorsStatus();",
" X[s] = ZeroExtend(status, 32);",
"",
" when MemOp_LOAD",
" // Tell the Exclusive Monitors to record a sequence of one or more atomic",
" // memory reads from virtual address range [address, address+dbytes-1].",
" // The Exclusive Monitor will only be set if all the reads are from the",
" // same dbytes-aligned physical address, to allow for the possibility of",
" // an atomicity break if the translation is changed between reads.",
" AArch64.SetExclusiveMonitors(address, dbytes);",
"",
" if pair then",
" if rt_unknown then",
" // ConstrainedUNPREDICTABLE case",
" X[t] = bits(datasize) UNKNOWN;",
" elsif elsize == 32 then",
" // 32-bit load exclusive pair (atomic)",
" data = Mem[address, dbytes, acctype];",
" if BigEndian() then",
" X[t] = data;",
" X[t2] = data;",
" else",
" X[t] = data;",
" X[t2] = data;",
" else // elsize == 64",
" // 64-bit load exclusive pair (not atomic),",
" // but must be 128-bit aligned",
" if address != Align(address, dbytes) then",
" iswrite = FALSE;",
" secondstage = FALSE;",
" AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage));",
" X[t] = Mem[address + 0, 8, acctype];",
" X[t2] = Mem[address + 8, 8, acctype];",
" else",
" data = Mem[address, dbytes, acctype];",
" X[t] = ZeroExtend(data, regsize);"
],
"variants": [
{
"pattern": "size#2 0 0 1 0 0 0 o2#1 L#1 o1#1 Rs#5 o0#1 Rt2#5 Rn#5 Rt#5",
"formats": [
{
"condition": "size == 10",
"format": "LDXR <Wt>, [<Xn|SP>{,#0}]"
},
{
"condition": "size == 11",
"format": "LDXR <Xt>, [<Xn|SP>{,#0}]"
}
],
"decoder": [
"integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"integer t2 = UInt(Rt2); // ignored by load/store single register",
"integer s = UInt(Rs); // ignored by all loads and store-release",
"",
"AccType acctype = if o0 == '1' then AccType_ORDERED else AccType_ATOMIC;",
"boolean pair = FALSE;",
"MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"integer elsize = 8 << UInt(size);",
"integer regsize = if elsize == 64 then 64 else 32;",
"integer datasize = if pair then elsize * 2 else elsize;"
]
}
],
"name": "LDXR",
"description": [
"Load Exclusive Register"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) data;",
"constant integer dbytes = datasize DIV 8;",
"boolean rt_unknown = FALSE;",
"boolean rn_unknown = FALSE;",
"",
"if memop == MemOp_LOAD && pair && t == t2 then",
" Constraint c = ConstrainUnpredictable(Unpredictable_LDPOVERLAP);",
" assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_UNKNOWN rt_unknown = TRUE; // result is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if memop == MemOp_STORE then",
" if s == t || (pair && s == t2) then",
" Constraint c = ConstrainUnpredictable(Unpredictable_DATAOVERLAP);",
" assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_UNKNOWN rt_unknown = TRUE; // store UNKNOWN value",
" when Constraint_NONE rt_unknown = FALSE; // store original value",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
" if s == n && n != 31 then",
" Constraint c = ConstrainUnpredictable(Unpredictable_BASEOVERLAP);",
" assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_UNKNOWN rn_unknown = TRUE; // address is UNKNOWN",
" when Constraint_NONE rn_unknown = FALSE; // address is original base",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"elsif rn_unknown then",
" address = bits(64) UNKNOWN;",
"else",
" address = X[n];",
"",
"case memop of",
" when MemOp_STORE",
" if rt_unknown then",
" data = bits(datasize) UNKNOWN;",
" elsif pair then",
" bits(datasize DIV 2) el1 = X[t];",
" bits(datasize DIV 2) el2 = X[t2];",
" data = if BigEndian() then el1 : el2 else el2 : el1;",
" else",
" data = X[t];",
"",
" bit status = '1';",
" // Check whether the Exclusive Monitors are set to include the",
" // physical memory locations corresponding to virtual address",
" // range [address, address+dbytes-1].",
" if AArch64.ExclusiveMonitorsPass(address, dbytes) then",
" // This atomic write will be rejected if it does not refer",
" // to the same physical locations after address translation.",
" Mem[address, dbytes, acctype] = data;",
" status = ExclusiveMonitorsStatus();",
" X[s] = ZeroExtend(status, 32);",
"",
" when MemOp_LOAD",
" // Tell the Exclusive Monitors to record a sequence of one or more atomic",
" // memory reads from virtual address range [address, address+dbytes-1].",
" // The Exclusive Monitor will only be set if all the reads are from the",
" // same dbytes-aligned physical address, to allow for the possibility of",
" // an atomicity break if the translation is changed between reads.",
" AArch64.SetExclusiveMonitors(address, dbytes);",
"",
" if pair then",
" if rt_unknown then",
" // ConstrainedUNPREDICTABLE case",
" X[t] = bits(datasize) UNKNOWN;",
" elsif elsize == 32 then",
" // 32-bit load exclusive pair (atomic)",
" data = Mem[address, dbytes, acctype];",
" if BigEndian() then",
" X[t] = data;",
" X[t2] = data;",
" else",
" X[t] = data;",
" X[t2] = data;",
" else // elsize == 64",
" // 64-bit load exclusive pair (not atomic),",
" // but must be 128-bit aligned",
" if address != Align(address, dbytes) then",
" iswrite = FALSE;",
" secondstage = FALSE;",
" AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage));",
" X[t] = Mem[address + 0, 8, acctype];",
" X[t2] = Mem[address + 8, 8, acctype];",
" else",
" data = Mem[address, dbytes, acctype];",
" X[t] = ZeroExtend(data, regsize);"
],
"variants": [
{
"pattern": "size#2 0 0 1 0 0 0 o2#1 L#1 o1#1 Rs#5 o0#1 Rt2#5 Rn#5 Rt#5",
"formats": [
{
"condition": null,
"format": "LDXRB <Wt>, [<Xn|SP>{,#0}]"
}
],
"decoder": [
"integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"integer t2 = UInt(Rt2); // ignored by load/store single register",
"integer s = UInt(Rs); // ignored by all loads and store-release",
"",
"AccType acctype = if o0 == '1' then AccType_ORDERED else AccType_ATOMIC;",
"boolean pair = FALSE;",
"MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"integer elsize = 8 << UInt(size);",
"integer regsize = if elsize == 64 then 64 else 32;",
"integer datasize = if pair then elsize * 2 else elsize;"
]
}
],
"name": "LDXRB",
"description": [
"Load Exclusive Register Byte"
]
}
{
"operation": [
"bits(64) address;",
"bits(datasize) data;",
"constant integer dbytes = datasize DIV 8;",
"boolean rt_unknown = FALSE;",
"boolean rn_unknown = FALSE;",
"",
"if memop == MemOp_LOAD && pair && t == t2 then",
" Constraint c = ConstrainUnpredictable(Unpredictable_LDPOVERLAP);",
" assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_UNKNOWN rt_unknown = TRUE; // result is UNKNOWN",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if memop == MemOp_STORE then",
" if s == t || (pair && s == t2) then",
" Constraint c = ConstrainUnpredictable(Unpredictable_DATAOVERLAP);",
" assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_UNKNOWN rt_unknown = TRUE; // store UNKNOWN value",
" when Constraint_NONE rt_unknown = FALSE; // store original value",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
" if s == n && n != 31 then",
" Constraint c = ConstrainUnpredictable(Unpredictable_BASEOVERLAP);",
" assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};",
" case c of",
" when Constraint_UNKNOWN rn_unknown = TRUE; // address is UNKNOWN",
" when Constraint_NONE rn_unknown = FALSE; // address is original base",
" when Constraint_UNDEF UnallocatedEncoding();",
" when Constraint_NOP EndOfInstruction();",
"",
"if n == 31 then",
" CheckSPAlignment();",
" address = SP[];",
"elsif rn_unknown then",
" address = bits(64) UNKNOWN;",
"else",
" address = X[n];",
"",
"case memop of",
" when MemOp_STORE",
" if rt_unknown then",
" data = bits(datasize) UNKNOWN;",
" elsif pair then",
" bits(datasize DIV 2) el1 = X[t];",
" bits(datasize DIV 2) el2 = X[t2];",
" data = if BigEndian() then el1 : el2 else el2 : el1;",
" else",
" data = X[t];",
"",
" bit status = '1';",
" // Check whether the Exclusive Monitors are set to include the",
" // physical memory locations corresponding to virtual address",
" // range [address, address+dbytes-1].",
" if AArch64.ExclusiveMonitorsPass(address, dbytes) then",
" // This atomic write will be rejected if it does not refer",
" // to the same physical locations after address translation.",
" Mem[address, dbytes, acctype] = data;",
" status = ExclusiveMonitorsStatus();",
" X[s] = ZeroExtend(status, 32);",
"",
" when MemOp_LOAD",
" // Tell the Exclusive Monitors to record a sequence of one or more atomic",
" // memory reads from virtual address range [address, address+dbytes-1].",
" // The Exclusive Monitor will only be set if all the reads are from the",
" // same dbytes-aligned physical address, to allow for the possibility of",
" // an atomicity break if the translation is changed between reads.",
" AArch64.SetExclusiveMonitors(address, dbytes);",
"",
" if pair then",
" if rt_unknown then",
" // ConstrainedUNPREDICTABLE case",
" X[t] = bits(datasize) UNKNOWN;",
" elsif elsize == 32 then",
" // 32-bit load exclusive pair (atomic)",
" data = Mem[address, dbytes, acctype];",
" if BigEndian() then",
" X[t] = data;",
" X[t2] = data;",
" else",
" X[t] = data;",
" X[t2] = data;",
" else // elsize == 64",
" // 64-bit load exclusive pair (not atomic),",
" // but must be 128-bit aligned",
" if address != Align(address, dbytes) then",
" iswrite = FALSE;",
" secondstage = FALSE;",
" AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage));",
" X[t] = Mem[address + 0, 8, acctype];",
" X[t2] = Mem[address + 8, 8, acctype];",
" else",
" data = Mem[address, dbytes, acctype];",
" X[t] = ZeroExtend(data, regsize);"
],
"variants": [
{
"pattern": "size#2 0 0 1 0 0 0 o2#1 L#1 o1#1 Rs#5 o0#1 Rt2#5 Rn#5 Rt#5",
"formats": [
{
"condition": null,
"format": "LDXRH <Wt>, [<Xn|SP>{,#0}]"
}
],
"decoder": [
"integer n = UInt(Rn);",
"integer t = UInt(Rt);",
"integer t2 = UInt(Rt2); // ignored by load/store single register",
"integer s = UInt(Rs); // ignored by all loads and store-release",
"",
"AccType acctype = if o0 == '1' then AccType_ORDERED else AccType_ATOMIC;",
"boolean pair = FALSE;",
"MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;",
"integer elsize = 8 << UInt(size);",
"integer regsize = if elsize == 64 then 64 else 32;",
"integer datasize = if pair then elsize * 2 else elsize;"
]
}
],
"name": "LDXRH",
"description": [
"Load Exclusive Register Halfword"
]
}
{
"operation": null,
"variants": [
{
"pattern": "sf#1 op#1 S#1 1 1 0 1 0 1 1 0 Rm#5 opcode2<5:2>#4 op2#2 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0",
"format": "LSL <Wd>, <Wn>, <Wm>"
},
{
"condition": "sf == 1",
"format": "LSL <Xd>, <Xn>, <Xm>"
}
],
"decoder": [
""
]
}
],
"name": "LSL (register)",
"description": [
"Logical Shift Left (register)"
]
}
{
"operation": null,
"variants": [
{
"pattern": "sf#1 opc#2 1 0 0 1 1 0 N#1 immr#6 imms#6 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0 && N == 0 && imms != 011111",
"format": "LSL <Wd>, <Wn>, #<shift>"
},
{
"condition": "sf == 1 && N == 1 && imms != 111111",
"format": "LSL <Xd>, <Xn>, #<shift>"
}
],
"decoder": [
""
]
}
],
"name": "LSL (immediate)",
"description": [
"Logical Shift Left (immediate)"
]
}
{
"operation": [
"bits(datasize) result;",
"bits(datasize) operand2 = X[m];",
"",
"result = ShiftReg(n, shift_type, UInt(operand2) MOD datasize);",
"X[d] = result;"
],
"variants": [
{
"pattern": "sf#1 op#1 S#1 1 1 0 1 0 1 1 0 Rm#5 opcode2<5:2>#4 op2#2 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0",
"format": "LSLV <Wd>, <Wn>, <Wm>"
},
{
"condition": "sf == 1",
"format": "LSLV <Xd>, <Xn>, <Xm>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer datasize = if sf == '1' then 64 else 32;",
"ShiftType shift_type = DecodeShift(op2);"
]
}
],
"name": "LSLV",
"description": [
"Logical Shift Left Variable"
]
}
{
"operation": null,
"variants": [
{
"pattern": "sf#1 op#1 S#1 1 1 0 1 0 1 1 0 Rm#5 opcode2<5:2>#4 op2#2 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0",
"format": "LSR <Wd>, <Wn>, <Wm>"
},
{
"condition": "sf == 1",
"format": "LSR <Xd>, <Xn>, <Xm>"
}
],
"decoder": [
""
]
}
],
"name": "LSR (register)",
"description": [
"Logical Shift Right (register)"
]
}
{
"operation": null,
"variants": [
{
"pattern": "sf#1 opc#2 1 0 0 1 1 0 N#1 immr#6 imms#6 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0 && N == 0 && imms == 011111",
"format": "LSR <Wd>, <Wn>, #<shift>"
},
{
"condition": "sf == 1 && N == 1 && imms == 111111",
"format": "LSR <Xd>, <Xn>, #<shift>"
}
],
"decoder": [
""
]
}
],
"name": "LSR (immediate)",
"description": [
"Logical Shift Right (immediate)"
]
}
{
"operation": [
"bits(datasize) result;",
"bits(datasize) operand2 = X[m];",
"",
"result = ShiftReg(n, shift_type, UInt(operand2) MOD datasize);",
"X[d] = result;"
],
"variants": [
{
"pattern": "sf#1 op#1 S#1 1 1 0 1 0 1 1 0 Rm#5 opcode2<5:2>#4 op2#2 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0",
"format": "LSRV <Wd>, <Wn>, <Wm>"
},
{
"condition": "sf == 1",
"format": "LSRV <Xd>, <Xn>, <Xm>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer datasize = if sf == '1' then 64 else 32;",
"ShiftType shift_type = DecodeShift(op2);"
]
}
],
"name": "LSRV",
"description": [
"Logical Shift Right Variable"
]
}
{
"operation": [
"bits(datasize) operand1 = X[n];",
"bits(datasize) operand2 = X[m];",
"bits(destsize) operand3 = X[a];",
"",
"integer result;",
"",
"if sub_op then",
" result = UInt(operand3) - (UInt(operand1) * UInt(operand2));",
"else",
" result = UInt(operand3) + (UInt(operand1) * UInt(operand2));",
"",
"X[d] = result;"
],
"variants": [
{
"pattern": "sf#1 op54#2 1 1 0 1 1 op31#3 Rm#5 o0#1 Ra#5 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0",
"format": "MADD <Wd>, <Wn>, <Wm>, <Wa>"
},
{
"condition": "sf == 1",
"format": "MADD <Xd>, <Xn>, <Xm>, <Xa>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"integer a = UInt(Ra);",
"integer destsize = if sf == '1' then 64 else 32;",
"integer datasize = destsize;",
"boolean sub_op = (o0 == '1');"
]
}
],
"name": "MADD",
"description": [
"Multiply-Add"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand1 = V[n];",
"bits(idxdsize) operand2 = V[m];",
"bits(datasize) operand3 = V[d];",
"bits(datasize) result;",
"integer element1;",
"integer element2;",
"bits(esize) product;",
"",
"element2 = UInt(Elem[operand2, index, esize]);",
"for e = 0 to elements-1",
" element1 = UInt(Elem[operand1, e, esize]);",
" product = (element1 * element2);",
" if sub_op then",
" Elem[result, e, esize] = Elem[operand3, e, esize] - product;",
" else",
" Elem[result, e, esize] = Elem[operand3, e, esize] + product;",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 1 size#2 L#1 M#1 Rm#4 0 o2#1 0 0 H#1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "MLA <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>]"
}
],
"decoder": [
"integer idxdsize = if H == '1' then 128 else 64; ",
"integer index;",
"bit Rmhi;",
"case size of",
" when '01' index = UInt(H:L:M); Rmhi = '0';",
" when '10' index = UInt(H:L); Rmhi = M;",
" otherwise UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rmhi:Rm);",
"",
"integer esize = 8 << UInt(size);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"boolean sub_op = (o2 == '1');"
]
}
],
"name": "MLA (by element)",
"description": [
"Multiply-Add to accumulator (vector, by element)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"bits(datasize) operand3 = V[d];",
"bits(datasize) result;",
"bits(esize) element1;",
"bits(esize) element2;",
"bits(esize) product;",
"",
"for e = 0 to elements-1",
" element1 = Elem[operand1, e, esize];",
" element2 = Elem[operand2, e, esize];",
" product = (UInt(element1) * UInt(element2));",
" if sub_op then",
" Elem[result, e, esize] = Elem[operand3, e, esize] - product;",
" else",
" Elem[result, e, esize] = Elem[operand3, e, esize] + product;",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 size#2 1 Rm#5 opcode#5 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "MLA <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"if size == '11' then ReservedValue();",
"integer esize = 8 << UInt(size);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"boolean sub_op = (U == '1');"
]
}
],
"name": "MLA (vector)",
"description": [
"Multiply-Add to accumulator (vector)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand1 = V[n];",
"bits(idxdsize) operand2 = V[m];",
"bits(datasize) operand3 = V[d];",
"bits(datasize) result;",
"integer element1;",
"integer element2;",
"bits(esize) product;",
"",
"element2 = UInt(Elem[operand2, index, esize]);",
"for e = 0 to elements-1",
" element1 = UInt(Elem[operand1, e, esize]);",
" product = (element1 * element2);",
" if sub_op then",
" Elem[result, e, esize] = Elem[operand3, e, esize] - product;",
" else",
" Elem[result, e, esize] = Elem[operand3, e, esize] + product;",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 1 size#2 L#1 M#1 Rm#4 0 o2#1 0 0 H#1 0 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "MLS <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>]"
}
],
"decoder": [
"integer idxdsize = if H == '1' then 128 else 64; ",
"integer index;",
"bit Rmhi;",
"case size of",
" when '01' index = UInt(H:L:M); Rmhi = '0';",
" when '10' index = UInt(H:L); Rmhi = M;",
" otherwise UnallocatedEncoding();",
"",
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rmhi:Rm);",
"",
"integer esize = 8 << UInt(size);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"boolean sub_op = (o2 == '1');"
]
}
],
"name": "MLS (by element)",
"description": [
"Multiply-Subtract from accumulator (vector, by element)"
]
}
{
"operation": [
"CheckFPAdvSIMDEnabled64();",
"bits(datasize) operand1 = V[n];",
"bits(datasize) operand2 = V[m];",
"bits(datasize) operand3 = V[d];",
"bits(datasize) result;",
"bits(esize) element1;",
"bits(esize) element2;",
"bits(esize) product;",
"",
"for e = 0 to elements-1",
" element1 = Elem[operand1, e, esize];",
" element2 = Elem[operand2, e, esize];",
" product = (UInt(element1) * UInt(element2));",
" if sub_op then",
" Elem[result, e, esize] = Elem[operand3, e, esize] - product;",
" else",
" Elem[result, e, esize] = Elem[operand3, e, esize] + product;",
"",
"V[d] = result;"
],
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 size#2 1 Rm#5 opcode#5 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "MLS <Vd>.<T>, <Vn>.<T>, <Vm>.<T>"
}
],
"decoder": [
"integer d = UInt(Rd);",
"integer n = UInt(Rn);",
"integer m = UInt(Rm);",
"if size == '11' then ReservedValue();",
"integer esize = 8 << UInt(size);",
"integer datasize = if Q == '1' then 128 else 64;",
"integer elements = datasize DIV esize;",
"",
"boolean sub_op = (U == '1');"
]
}
],
"name": "MLS (vector)",
"description": [
"Multiply-Subtract from accumulator (vector)"
]
}
{
"operation": null,
"variants": [
{
"pattern": "sf#1 op54#2 1 1 0 1 1 op31#3 Rm#5 o0#1 Ra#5 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0",
"format": "MNEG <Wd>, <Wn>, <Wm>"
},
{
"condition": "sf == 1",
"format": "MNEG <Xd>, <Xn>, <Xm>"
}
],
"decoder": [
""
]
}
],
"name": "MNEG",
"description": [
"Multiply-Negate"
]
}
{
"operation": null,
"variants": [
{
"pattern": "sf#1 op#1 S#1 1 0 0 0 1 shift#2 imm12#12 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0",
"format": "MOV <Wd|WSP>, <Wn|WSP>"
},
{
"condition": "sf == 1",
"format": "MOV <Xd|SP>, <Xn|SP>"
}
],
"decoder": [
""
]
}
],
"name": "MOV (to/from SP)",
"description": [
"Move between register and stack pointer",
"Rd = Rn"
]
}
{
"operation": null,
"variants": [
{
"pattern": "0 1 op#1 1 1 1 1 0 0 0 0 imm5#5 0 imm4#4 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "MOV <V><d>, <Vn>.<T>[<index>]"
}
],
"decoder": [
""
]
}
],
"name": "MOV (scalar)",
"description": [
"Move vector element to scalar"
]
}
{
"operation": null,
"variants": [
{
"pattern": "0 Q#1 op#1 0 1 1 1 0 0 0 0 imm5#5 0 imm4#4 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "MOV <Vd>.<Ts>[<index1>], <Vn>.<Ts>[<index2>]"
}
],
"decoder": [
""
]
}
],
"name": "MOV (element)",
"description": [
"Move vector element to another vector element"
]
}
{
"operation": null,
"variants": [
{
"pattern": "0 Q#1 op#1 0 1 1 1 0 0 0 0 imm5#5 0 imm4#4 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "MOV <Vd>.<Ts>[<index>], <R><n>"
}
],
"decoder": [
""
]
}
],
"name": "MOV (from general)",
"description": [
"Move general-purpose register to a vector element"
]
}
{
"operation": null,
"variants": [
{
"pattern": "sf#1 opc#2 1 0 0 1 0 1 hw#2 imm16#16 Rd#5",
"formats": [
{
"condition": "sf == 0",
"format": "MOV <Wd>, #<imm>"
},
{
"condition": "sf == 1",
"format": "MOV <Xd>, #<imm>"
}
],
"decoder": [
""
]
}
],
"name": "MOV (inverted wide immediate)",
"description": [
"Move (inverted wide immediate)"
]
}
{
"operation": null,
"variants": [
{
"pattern": "sf#1 opc#2 1 0 0 1 0 1 hw#2 imm16#16 Rd#5",
"formats": [
{
"condition": "sf == 0",
"format": "MOV <Wd>, #<imm>"
},
{
"condition": "sf == 1",
"format": "MOV <Xd>, #<imm>"
}
],
"decoder": [
""
]
}
],
"name": "MOV (wide immediate)",
"description": [
"Move (wide immediate)"
]
}
{
"operation": null,
"variants": [
{
"pattern": "0 Q#1 U#1 0 1 1 1 0 size#2 1 Rm#5 opcode#5 1 Rn#5 Rd#5",
"formats": [
{
"condition": null,
"format": "MOV <Vd>.<T>, <Vn>.<T>"
}
],
"decoder": [
""
]
}
],
"name": "MOV (vector)",
"description": [
"Move vector"
]
}
{
"operation": null,
"variants": [
{
"pattern": "sf#1 opc#2 1 0 0 1 0 0 N#1 immr#6 imms#6 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0 && N == 0",
"format": "MOV <Wd|WSP>, #<imm>"
},
{
"condition": "sf == 1",
"format": "MOV <Xd|SP>, #<imm>"
}
],
"decoder": [
""
]
}
],
"name": "MOV (bitmask immediate)",
"description": [
"Move (bitmask immediate)"
]
}
{
"operation": null,
"variants": [
{
"pattern": "sf#1 opc#2 0 1 0 1 0 shift#2 N#1 Rm#5 imm6#6 Rn#5 Rd#5",
"formats": [
{
"condition": "sf == 0",
"format
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment