/* TSTART */ | TSTART xreg { if not (isregzr $2) then error_registers ("expected " ^ $1.txt ^ " ") else `AArch64TMStart $2 } /* TCOMMIT */ | TCOMMIT { `AArch64TMCommit } /* TABORT */ | TABORT imm { if not (iskbituimm 6 $2) then error_arg " must be in the range 0 to 63" else `AArch64TMAbort (($2 lsr 5) <> 0, $2 mod 32) } /* TTEST */ | TTEST {`AArch64TMTest} | ADCSBC wreg COMMA wreg COMMA wreg { if not (isregzr $2 && isregzr $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , ") else `AArch64AddSubCarry ($2,$4,$6,Set32,$1.sub_op,$1.setflags) } | ADCSBC xreg COMMA xreg COMMA xreg { if not (isregzr $2 && isregzr $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , ") else `AArch64AddSubCarry ($2,$4,$6,Set64,$1.sub_op,$1.setflags) } /* ADC/ADCS/SBC/SBCS */ | ADCSBC wreg COMMA wreg COMMA wreg { if not (isregzr $2 && isregzr $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , ") else `AArch64AddSubCarry ($2,$4,$6,Set32,$1.sub_op,$1.setflags) } | ADCSBC xreg COMMA xreg COMMA xreg { if not (isregzr $2 && isregzr $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , ") else `AArch64AddSubCarry ($2,$4,$6,Set64,$1.sub_op,$1.setflags) } /* ADD/SUB/ADDS/SUBS (extended register), and when noted (shifted register) */ | ADDSUB wreg COMMA wreg COMMA wreg { (* ambiguous with (shifted register) *) if $1.setflags && not (isregzr $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") else if not $1.setflags && not (isregsp $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") else `AArch64AddSubExtendRegister ($2,$4,$6,Set32,$1.sub_op,$1.setflags,ExtendType_UXTW,0) } | ADDSUB wreg COMMA wreg COMMA wreg COMMA EXTEND { if $1.setflags && not (isregzr $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") else if not $1.setflags && not (isregsp $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") else `AArch64AddSubExtendRegister ($2,$4,$6,Set32,$1.sub_op,$1.setflags,$8._type,0) } | ADDSUB wreg COMMA wreg COMMA wreg COMMA SHIFT { if $1.setflags && not (isregzr $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") else if (not $1.setflags) && not (isregsp $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") else if not ($8.shift_type = ShiftType_LSL) then error_arg " must be one of UXTB,UXTH,UXTW,UXTX,SXTB,SXTH,SXTW,SXTX,LSL" else `AArch64AddSubExtendRegister ($2,$4,$6,Set32,$1.sub_op,$1.setflags,ExtendType_UXTW,0) } | ADDSUB wreg COMMA wreg COMMA wreg COMMA EXTEND imm { if $1.setflags && not (isregzr $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") else if not $1.setflags && not (isregsp $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") else if not (0 <= $9 && $9 <= 4) then error_arg " must be in the range 0 to 4" else `AArch64AddSubExtendRegister ($2,$4,$6,Set32,$1.sub_op,$1.setflags,$8._type,$9) } | ADDSUB wreg COMMA wreg COMMA wreg COMMA SHIFT imm { if (issp $2 || issp $4) then begin (* (extended register) *) if $1.setflags && not (isregzr $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") else if not $1.setflags && not (isregsp $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") else if not ($8.shift_type = ShiftType_LSL) then error_arg " must be one of UXTB,UXTH,UXTW,UXTX,SXTB,SXTH,SXTW,SXTX,LSL" else if not (0 <= $9 && $9 <= 4) then error_arg " must be in the range 0 to 4" else `AArch64AddSubExtendRegister ($2,$4,$6,Set32,$1.sub_op,$1.setflags,ExtendType_UXTW,$9) end else begin (* (shifted register) *) if not (isregzr $2 && isregzr $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, #}") else if $8.shift_type = ShiftType_ROR then error_arg " must be one of LSL,LSR,ASR" else if not (0 <= $9 && $9 <= 31) then error_arg " must be in the range 0 to 31" else `AArch64AddSubShiftedRegister ($2,$4,$6,Set32,$1.sub_op,$1.setflags,$8.shift_type,$9) end } | ADDSUB xreg COMMA xreg COMMA xreg { (* ambiguous with (shifted register) *) if $1.setflags && not (isregzr $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") else if not $1.setflags && not (isregsp $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") else `AArch64AddSubExtendRegister ($2,$4,$6,Set64,$1.sub_op,$1.setflags,ExtendType_UXTX,0) } | ADDSUB xreg COMMA xreg COMMA wreg COMMA EXTEND { if $1.setflags && not (isregzr $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") else if not $1.setflags && not (isregsp $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") else if $8._type = ExtendType_UXTX || $8._type = ExtendType_SXTX then error_arg " doesn't match " else `AArch64AddSubExtendRegister ($2,$4,$6,Set64,$1.sub_op,$1.setflags,$8._type,0) } | ADDSUB xreg COMMA xreg COMMA wreg COMMA SHIFT { if $1.setflags && not (isregzr $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") else if not $1.setflags && not (isregsp $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") else if not ($8.shift_type = ShiftType_LSL) then error_arg " must be one of UXTB,UXTH,UXTW,UXTX,SXTB,SXTH,SXTW,SXTX,LSL" else `AArch64AddSubExtendRegister ($2,$4,$6,Set64,$1.sub_op,$1.setflags,ExtendType_UXTX,0) } | ADDSUB xreg COMMA xreg COMMA wreg COMMA EXTEND imm { if $1.setflags && not (isregzr $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") else if not $1.setflags && not (isregsp $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") else if not (0 <= $9 && $9 <= 4) then error_arg " must be in the range 0 to 4." else if $8._type = ExtendType_UXTX || $8._type = ExtendType_SXTX then error_arg " doesn't match " else `AArch64AddSubExtendRegister ($2,$4,$6,Set64,$1.sub_op,$1.setflags,$8._type,$9) } | ADDSUB xreg COMMA xreg COMMA wreg COMMA SHIFT imm { if $1.setflags && not (isregzr $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") else if not $1.setflags && not (isregsp $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") else if not ($8.shift_type = ShiftType_LSL) then error_arg " must be one of UXTB,UXTH,UXTW,UXTX,SXTB,SXTH,SXTW,SXTX,LSL" else if not (0 <= $9 && $9 <= 4) then error_arg " must be in the range 0 to 4." else `AArch64AddSubExtendRegister ($2,$4,$6,Set64,$1.sub_op,$1.setflags,ExtendType_UXTX,$9) } | ADDSUB xreg COMMA xreg COMMA xreg COMMA EXTEND { if $1.setflags && not (isregzr $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") else if not $1.setflags && not (isregsp $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") else if not ($8._type = ExtendType_UXTX || $8._type = ExtendType_SXTX) then error_arg " doesn't match " else `AArch64AddSubExtendRegister ($2,$4,$6,Set64,$1.sub_op,$1.setflags,$8._type,0) } | ADDSUB xreg COMMA xreg COMMA xreg COMMA SHIFT { if $1.setflags && not (isregzr $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") else if not $1.setflags && not (isregsp $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") else if not ($8.shift_type = ShiftType_LSL) then error_arg " must be one of UXTB,UXTH,UXTW,UXTX,SXTB,SXTH,SXTW,SXTX,LSL" else `AArch64AddSubExtendRegister ($2,$4,$6,Set64,$1.sub_op,$1.setflags,ExtendType_UXTX,0) } | ADDSUB xreg COMMA xreg COMMA xreg COMMA EXTEND imm { if $1.setflags && not (isregzr $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") else if not $1.setflags && not (isregsp $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") else if not (0 <= $9 && $9 <= 4) then error_arg " must be in the range 0 to 4." else if not ($8._type = ExtendType_UXTX || $8._type = ExtendType_SXTX) then error_arg " doesn't match " else `AArch64AddSubExtendRegister ($2,$4,$6,Set64,$1.sub_op,$1.setflags,$8._type,$9) } | ADDSUB xreg COMMA xreg COMMA xreg COMMA SHIFT imm { if (issp $2 || issp $4) then begin (* (extended register) *) if $1.setflags && not (isregzr $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") else if not $1.setflags && not (isregsp $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, {#}}") else if not ($8.shift_type = ShiftType_LSL) then error_arg " must be one of UXTB,UXTH,UXTW,UXTX,SXTB,SXTH,SXTW,SXTX,LSL" else if not (0 <= $9 && $9 <= 4) then error_arg " must be in the range 0 to 4." else `AArch64AddSubExtendRegister ($2,$4,$6,Set64,$1.sub_op,$1.setflags,ExtendType_UXTX,$9) end else begin (* (shifted register) *) if not (isregzr $2 && isregzr $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " , , {, #}") else if $8.shift_type = ShiftType_ROR then error_arg " must be one of LSL,LSR,ASR" else if not (0 <= $9 && $9 <= 63) then error_arg " must be in the range 0 to 63" else `AArch64AddSubShiftedRegister ($2,$4,$6,Set64,$1.sub_op,$1.setflags,$8.shift_type,$9) end } /* ADD/SUB/ADDS/SUBS (immediate) */ | ADDSUB wreg COMMA wreg COMMA imm { if $1.setflags && not (isregzr $2 && isregsp $4) then error_registers ("expected " ^ $1.txt ^ " , , #{, }") else if not $1.setflags && not (isregsp $2 && isregsp $4) then error_registers ("expected " ^ $1.txt ^ " , , #{, }") else if not (0 <= $6 && $6 <= 4095) then error_arg " must be in the range 0 to 4095" else `AArch64AddSubImmediate ($2,$4,Set32,$1.sub_op,$1.setflags,reg_size_bits_R32_of_int $6) } | ADDSUB wreg COMMA wreg COMMA imm COMMA SHIFT imm { if $1.setflags && not (isregzr $2 && isregsp $4) then error_registers ("expected " ^ $1.txt ^ " , , #{, }") else if not $1.setflags && not (isregsp $2 && isregsp $4) then error_registers ("expected " ^ $1.txt ^ " , , #{, }") else if not (0 <= $6 && $6 <= 4095) then error_arg " must be in the range 0 to 4095" else if not ($8.shift_type = ShiftType_LSL && ($9 = 0 || $9 = 12)) then error_arg " must be 'LSL #0' or 'LSL #12'" else `AArch64AddSubImmediate ($2,$4,Set32,$1.sub_op,$1.setflags,reg_size_bits_R32_of_int ($6 lsl $9)) } | ADDSUB xreg COMMA xreg COMMA imm { if $1.setflags && not (isregzr $2 && isregsp $4) then error_registers ("expected " ^ $1.txt ^ " , , #{, }") else if not $1.setflags && not (isregsp $2 && isregsp $4) then error_registers ("expected " ^ $1.txt ^ " , , #{, }") else if not (0 <= $6 && $6 <= 4095) then error_arg " must be in the range 0 to 4095" else `AArch64AddSubImmediate ($2,$4,Set64,$1.sub_op,$1.setflags,reg_size_bits_R64_of_int $6) } | ADDSUB xreg COMMA xreg COMMA imm COMMA SHIFT imm { if $1.setflags && not (isregzr $2 && isregsp $4) then error_registers ("expected " ^ $1.txt ^ " , , #{, }") else if not $1.setflags && not (isregsp $2 && isregsp $4) then error_registers ("expected " ^ $1.txt ^ " , , #{, }") else if not (0 <= $6 && $6 <= 4095) then error_arg " must be in the range 0 to 4095" else if not ($8.shift_type = ShiftType_LSL && ($9 = 0 || $9 = 12)) then error_arg " must be 'LSL #0' or 'LSL #12'" else `AArch64AddSubImmediate ($2,$4,Set64,$1.sub_op,$1.setflags,reg_size_bits_R64_of_int ($6 lsl $9)) } /* ADR/ADRP */ /* | ADR xreg COMMA NAME { if not (isregzr $2) then error_registers ("expected " ^ $1.txt ^ " ,