Created
May 7, 2017 19:15
-
-
Save agustingianni/2d78a1607afcefed06c77748b9c371ee to your computer and use it in GitHub Desktop.
This file has been truncated, but you can view the full file.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "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