mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-22 10:29:35 +00:00
Select ADC, SBC, and RSC instead of the ADCS, SBCS, and RSCS when the carry bit def is not used.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74228 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
0b49c32c56
commit
6267422318
@ -103,6 +103,8 @@ def HasThumb2 : Predicate<"Subtarget->hasThumb2()">;
|
||||
def IsARM : Predicate<"!Subtarget->isThumb()">;
|
||||
def IsDarwin : Predicate<"Subtarget->isTargetDarwin()">;
|
||||
def IsNotDarwin : Predicate<"!Subtarget->isTargetDarwin()">;
|
||||
def CarryDefIsUnused : Predicate<"N.getNode()->hasNUsesOfValue(0, 1)">;
|
||||
def CarryDefIsUsed : Predicate<"N.getNode()->hasAnyUseOfValue(1)">;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ARM Flag Definitions.
|
||||
@ -430,19 +432,40 @@ multiclass AI_bin_rrot<bits<8> opcod, string opc, PatFrag opnode> {
|
||||
Requires<[IsARM, HasV6]>;
|
||||
}
|
||||
|
||||
/// AI1_bin_cs_irs - A binary operation that both uses and defines CPSR. It's
|
||||
/// currently not predicable.
|
||||
let Defs = [CPSR], Uses = [CPSR] in {
|
||||
multiclass AI1_bin_cs_irs<bits<4> opcod, string opc, PatFrag opnode> {
|
||||
def ri : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
|
||||
/// AI1_adde_sube_irs - Define instructions and patterns for adde and sube.
|
||||
let Uses = [CPSR] in {
|
||||
multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode> {
|
||||
def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
|
||||
DPFrm, opc, " $dst, $a, $b",
|
||||
[(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>,
|
||||
Requires<[IsARM, CarryDefIsUnused]>;
|
||||
def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
|
||||
DPFrm, opc, " $dst, $a, $b",
|
||||
[(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
|
||||
Requires<[IsARM, CarryDefIsUnused]>;
|
||||
def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
|
||||
DPSoRegFrm, opc, " $dst, $a, $b",
|
||||
[(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>,
|
||||
Requires<[IsARM, CarryDefIsUnused]>;
|
||||
// Carry setting variants
|
||||
def Sri : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
|
||||
DPFrm, !strconcat(opc, "s $dst, $a, $b"),
|
||||
[(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>;
|
||||
def rr : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
|
||||
[(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>,
|
||||
Requires<[IsARM, CarryDefIsUsed]> {
|
||||
let Defs = [CPSR];
|
||||
}
|
||||
def Srr : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
|
||||
DPFrm, !strconcat(opc, "s $dst, $a, $b"),
|
||||
[(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>;
|
||||
def rs : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
|
||||
[(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
|
||||
Requires<[IsARM, CarryDefIsUsed]> {
|
||||
let Defs = [CPSR];
|
||||
}
|
||||
def Srs : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
|
||||
DPSoRegFrm, !strconcat(opc, "s $dst, $a, $b"),
|
||||
[(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>;
|
||||
[(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>,
|
||||
Requires<[IsARM, CarryDefIsUsed]> {
|
||||
let Defs = [CPSR];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -910,11 +933,10 @@ defm ADDS : AI1_bin_s_irs<0b0100, "add",
|
||||
defm SUBS : AI1_bin_s_irs<0b0010, "sub",
|
||||
BinOpFrag<(subc node:$LHS, node:$RHS)>>;
|
||||
|
||||
// FIXME: Do not allow ADCS / SBCS to be predicated for now.
|
||||
defm ADCS : AI1_bin_cs_irs<0b0101, "adc",
|
||||
BinOpFrag<(adde node:$LHS, node:$RHS)>>;
|
||||
defm SBCS : AI1_bin_cs_irs<0b0110, "sbc",
|
||||
BinOpFrag<(sube node:$LHS, node:$RHS)>>;
|
||||
defm ADC : AI1_adde_sube_irs<0b0101, "adc",
|
||||
BinOpFrag<(adde node:$LHS, node:$RHS)>>;
|
||||
defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
|
||||
BinOpFrag<(sube node:$LHS, node:$RHS)>>;
|
||||
|
||||
// These don't define reg/reg forms, because they are handled above.
|
||||
def RSBri : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
|
||||
@ -935,14 +957,27 @@ def RSBSrs : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
|
||||
[(set GPR:$dst, (subc so_reg:$b, GPR:$a))]>;
|
||||
}
|
||||
|
||||
// FIXME: Do not allow RSC to be predicated for now.
|
||||
let Uses = [CPSR] in {
|
||||
def RSCri : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
|
||||
DPFrm, "rsc", " $dst, $a, $b",
|
||||
[(set GPR:$dst, (sube so_imm:$b, GPR:$a))]>,
|
||||
Requires<[IsARM, CarryDefIsUnused]>;
|
||||
def RSCrs : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
|
||||
DPSoRegFrm, "rsc", " $dst, $a, $b",
|
||||
[(set GPR:$dst, (sube so_reg:$b, GPR:$a))]>,
|
||||
Requires<[IsARM, CarryDefIsUnused]>;
|
||||
}
|
||||
|
||||
// FIXME: Allow these to be predicated.
|
||||
let Defs = [CPSR], Uses = [CPSR] in {
|
||||
def RSCSri : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
|
||||
DPFrm, "rscs $dst, $a, $b",
|
||||
[(set GPR:$dst, (sube so_imm:$b, GPR:$a))]>;
|
||||
[(set GPR:$dst, (sube so_imm:$b, GPR:$a))]>,
|
||||
Requires<[IsARM, CarryDefIsUnused]>;
|
||||
def RSCSrs : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
|
||||
DPSoRegFrm, "rscs $dst, $a, $b",
|
||||
[(set GPR:$dst, (sube so_reg:$b, GPR:$a))]>;
|
||||
[(set GPR:$dst, (sube so_reg:$b, GPR:$a))]>,
|
||||
Requires<[IsARM, CarryDefIsUnused]>;
|
||||
}
|
||||
|
||||
// (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
|
||||
|
@ -223,43 +223,80 @@ multiclass T2I_bin_ii12rs<string opc, PatFrag opnode> {
|
||||
[(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>;
|
||||
}
|
||||
|
||||
/// T2I_bin_cs_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a
|
||||
/// T2I_adde_sube_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a
|
||||
/// binary operation that produces a value and use and define the carry bit.
|
||||
/// It's not predicable.
|
||||
let Defs = [CPSR], Uses = [CPSR] in {
|
||||
multiclass T2I_bin_cs_irs<string opc, PatFrag opnode> {
|
||||
let Uses = [CPSR] in {
|
||||
multiclass T2I_adde_sube_irs<string opc, PatFrag opnode> {
|
||||
// shifted imm
|
||||
def ri : T2XI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs),
|
||||
!strconcat(opc, "s $dst, $lhs, $rhs"),
|
||||
[(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>;
|
||||
def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs),
|
||||
opc, " $dst, $lhs, $rhs",
|
||||
[(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>,
|
||||
Requires<[IsThumb, HasThumb2, CarryDefIsUnused]>;
|
||||
// register
|
||||
def rr : T2XI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs),
|
||||
!strconcat(opc, "s $dst, $lhs, $rhs"),
|
||||
[(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>;
|
||||
def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs),
|
||||
opc, " $dst, $lhs, $rhs",
|
||||
[(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>,
|
||||
Requires<[IsThumb, HasThumb2, CarryDefIsUnused]>;
|
||||
// shifted register
|
||||
def rs : T2XI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs),
|
||||
!strconcat(opc, "s $dst, $lhs, $rhs"),
|
||||
[(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>;
|
||||
def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs),
|
||||
opc, "s $dst, $lhs, $rhs",
|
||||
[(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>,
|
||||
Requires<[IsThumb, HasThumb2, CarryDefIsUnused]>;
|
||||
// Carry setting variants
|
||||
// shifted imm
|
||||
def Sri : T2XI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs),
|
||||
!strconcat(opc, "s $dst, $lhs, $rhs"),
|
||||
[(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>,
|
||||
Requires<[IsThumb, HasThumb2, CarryDefIsUsed]> {
|
||||
let Defs = [CPSR];
|
||||
}
|
||||
// register
|
||||
def Srr : T2XI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs),
|
||||
!strconcat(opc, "s $dst, $lhs, $rhs"),
|
||||
[(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>,
|
||||
Requires<[IsThumb, HasThumb2, CarryDefIsUsed]> {
|
||||
let Defs = [CPSR];
|
||||
}
|
||||
// shifted register
|
||||
def Srs : T2XI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs),
|
||||
!strconcat(opc, "s $dst, $lhs, $rhs"),
|
||||
[(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>,
|
||||
Requires<[IsThumb, HasThumb2, CarryDefIsUsed]> {
|
||||
let Defs = [CPSR];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// T2I_rbin_cs_is - Same as T2I_bin_cs_irs except the order of operands are
|
||||
/// T2I_rsc_is - Same as T2I_adde_sube_irs except the order of operands are
|
||||
/// reversed. It doesn't define the 'rr' form since it's handled by its
|
||||
/// T2I_bin_cs_irs counterpart.
|
||||
/// T2I_adde_sube_irs counterpart.
|
||||
let Defs = [CPSR], Uses = [CPSR] in {
|
||||
multiclass T2I_rbin_cs_is<string opc, PatFrag opnode> {
|
||||
multiclass T2I_rsc_is<string opc, PatFrag opnode> {
|
||||
// shifted imm
|
||||
def ri : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs),
|
||||
!strconcat(opc, "s $dst, $rhs, $lhs"),
|
||||
[(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>;
|
||||
// register
|
||||
def rr : T2XI<(outs GPR:$dst), (ins GPR:$rhs, GPR:$lhs),
|
||||
!strconcat(opc, "s $dst, $rhs, $lhs"),
|
||||
[(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>;
|
||||
def ri : T2sI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs),
|
||||
opc, " $dst, $rhs, $lhs",
|
||||
[(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>,
|
||||
Requires<[IsThumb, HasThumb2, CarryDefIsUnused]>;
|
||||
// shifted register
|
||||
def rs : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs),
|
||||
def rs : T2sI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs),
|
||||
opc, " $dst, $rhs, $lhs",
|
||||
[(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]>,
|
||||
Requires<[IsThumb, HasThumb2, CarryDefIsUnused]>;
|
||||
// shifted imm
|
||||
def Sri : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs),
|
||||
!strconcat(opc, "s $dst, $rhs, $lhs"),
|
||||
[(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]>;
|
||||
[(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>,
|
||||
Requires<[IsThumb, HasThumb2, CarryDefIsUsed]> {
|
||||
let Defs = [CPSR];
|
||||
}
|
||||
// shifted register
|
||||
def Srs : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs),
|
||||
!strconcat(opc, "s $dst, $rhs, $lhs"),
|
||||
[(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]>,
|
||||
Requires<[IsThumb, HasThumb2, CarryDefIsUsed]> {
|
||||
let Defs = [CPSR];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -385,14 +422,13 @@ defm t2SUB : T2I_bin_ii12rs<"sub", BinOpFrag<(sub node:$LHS, node:$RHS)>>;
|
||||
defm t2ADDS : T2I_bin_s_irs <"add", BinOpFrag<(addc node:$LHS, node:$RHS)>>;
|
||||
defm t2SUBS : T2I_bin_s_irs <"sub", BinOpFrag<(subc node:$LHS, node:$RHS)>>;
|
||||
|
||||
// FIXME: predication support
|
||||
defm t2ADC : T2I_bin_cs_irs<"adc", BinOpFrag<(adde node:$LHS, node:$RHS)>>;
|
||||
defm t2SBC : T2I_bin_cs_irs<"sbc", BinOpFrag<(sube node:$LHS, node:$RHS)>>;
|
||||
defm t2ADC : T2I_adde_sube_irs<"adc", BinOpFrag<(adde node:$LHS, node:$RHS)>>;
|
||||
defm t2SBC : T2I_adde_sube_irs<"sbc", BinOpFrag<(sube node:$LHS, node:$RHS)>>;
|
||||
|
||||
// RSB, RSC
|
||||
defm t2RSB : T2I_rbin_is <"rsb", BinOpFrag<(sub node:$LHS, node:$RHS)>>;
|
||||
defm t2RSBS : T2I_rbin_s_is <"rsb", BinOpFrag<(subc node:$LHS, node:$RHS)>>;
|
||||
defm t2RSC : T2I_rbin_cs_is<"rsc", BinOpFrag<(sube node:$LHS, node:$RHS)>>;
|
||||
defm t2RSC : T2I_rsc_is <"rsc", BinOpFrag<(sube node:$LHS, node:$RHS)>>;
|
||||
|
||||
// (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
|
||||
def : Thumb2Pat<(add GPR:$src, t2_so_imm_neg:$imm),
|
||||
|
@ -1,6 +1,6 @@
|
||||
; RUN: llvm-as < %s | llc -march=arm | grep "subs r" | count 2
|
||||
; RUN: llvm-as < %s | llc -march=arm | grep adc
|
||||
; RUN: llvm-as < %s | llc -march=arm | grep sbc
|
||||
; RUN: llvm-as < %s | llc -march=arm | grep "adc r"
|
||||
; RUN: llvm-as < %s | llc -march=arm | grep "sbc r" | count 2
|
||||
|
||||
define i64 @f1(i64 %a, i64 %b) {
|
||||
entry:
|
||||
|
@ -1,6 +1,6 @@
|
||||
; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep "subs r" | count 2
|
||||
; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep adc
|
||||
; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep sbc
|
||||
; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep "adc r"
|
||||
; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep "sbc r" | count 2
|
||||
|
||||
define i64 @f1(i64 %a, i64 %b) {
|
||||
entry:
|
||||
|
Loading…
Reference in New Issue
Block a user