Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
S
swiftshader
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
swiftshader
Commits
2f5534f1
Commit
2f5534f1
authored
Sep 18, 2015
by
John Porto
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Subzero. ARM32 Fcmp lowering.
BUG=
https://code.google.com/p/nativeclient/issues/detail?id=4076
R=stichnot@chromium.org Review URL:
https://codereview.chromium.org/1356763004
.
parent
be87b2ec
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
495 additions
and
40 deletions
+495
-40
IceInstARM32.cpp
src/IceInstARM32.cpp
+82
-8
IceInstARM32.h
src/IceInstARM32.h
+42
-0
IceTargetLoweringARM32.cpp
src/IceTargetLoweringARM32.cpp
+94
-18
IceTargetLoweringARM32.def
src/IceTargetLoweringARM32.def
+40
-12
IceTargetLoweringARM32.h
src/IceTargetLoweringARM32.h
+9
-2
fp.cmp.ll
tests_lit/llvm2ice_tests/fp.cmp.ll
+228
-0
No files found.
src/IceInstARM32.cpp
View file @
2f5534f1
...
@@ -382,6 +382,16 @@ InstARM32Vcvt::InstARM32Vcvt(Cfg *Func, Variable *Dest, Variable *Src,
...
@@ -382,6 +382,16 @@ InstARM32Vcvt::InstARM32Vcvt(Cfg *Func, Variable *Dest, Variable *Src,
addSource
(
Src
);
addSource
(
Src
);
}
}
InstARM32Vcmp
::
InstARM32Vcmp
(
Cfg
*
Func
,
Variable
*
Src0
,
Variable
*
Src1
,
CondARM32
::
Cond
Predicate
)
:
InstARM32Pred
(
Func
,
InstARM32
::
Vcmp
,
2
,
nullptr
,
Predicate
)
{
addSource
(
Src0
);
addSource
(
Src1
);
}
InstARM32Vmrs
::
InstARM32Vmrs
(
Cfg
*
Func
,
CondARM32
::
Cond
Predicate
)
:
InstARM32Pred
(
Func
,
InstARM32
::
Vmrs
,
0
,
nullptr
,
Predicate
)
{}
// ======================== Dump routines ======================== //
// ======================== Dump routines ======================== //
// Two-addr ops
// Two-addr ops
...
@@ -507,8 +517,7 @@ void InstARM32Vmov::emitMultiDestSingleSource(const Cfg *Func) const {
...
@@ -507,8 +517,7 @@ void InstARM32Vmov::emitMultiDestSingleSource(const Cfg *Func) const {
assert
(
!
llvm
::
isa
<
OperandARM32Mem
>
(
Src0
));
assert
(
!
llvm
::
isa
<
OperandARM32Mem
>
(
Src0
));
Str
<<
"
\t
"
Str
<<
"
\t
"
<<
"vmov"
<<
"vmov"
<<
getPredicate
()
<<
"
\t
"
;
<<
"
\t
"
;
Dest0
->
emit
(
Func
);
Dest0
->
emit
(
Func
);
Str
<<
", "
;
Str
<<
", "
;
Dest1
->
emit
(
Func
);
Dest1
->
emit
(
Func
);
...
@@ -529,8 +538,7 @@ void InstARM32Vmov::emitSingleDestMultiSource(const Cfg *Func) const {
...
@@ -529,8 +538,7 @@ void InstARM32Vmov::emitSingleDestMultiSource(const Cfg *Func) const {
assert
(
!
llvm
::
isa
<
OperandARM32Mem
>
(
Src1
));
assert
(
!
llvm
::
isa
<
OperandARM32Mem
>
(
Src1
));
Str
<<
"
\t
"
Str
<<
"
\t
"
<<
"vmov"
<<
"vmov"
<<
getPredicate
()
<<
"
\t
"
;
<<
"
\t
"
;
Dest0
->
emit
(
Func
);
Dest0
->
emit
(
Func
);
Str
<<
", "
;
Str
<<
", "
;
Src0
->
emit
(
Func
);
Src0
->
emit
(
Func
);
...
@@ -549,6 +557,14 @@ bool isVariableWithoutRegister(const Operand *Op) {
...
@@ -549,6 +557,14 @@ bool isVariableWithoutRegister(const Operand *Op) {
bool
isMemoryAccess
(
Operand
*
Op
)
{
bool
isMemoryAccess
(
Operand
*
Op
)
{
return
isVariableWithoutRegister
(
Op
)
||
llvm
::
isa
<
OperandARM32Mem
>
(
Op
);
return
isVariableWithoutRegister
(
Op
)
||
llvm
::
isa
<
OperandARM32Mem
>
(
Op
);
}
}
bool
isMoveBetweenCoreAndVFPRegisters
(
Variable
*
Dest
,
Operand
*
Src
)
{
const
Type
DestTy
=
Dest
->
getType
();
const
Type
SrcTy
=
Src
->
getType
();
assert
(
!
(
isScalarIntegerType
(
DestTy
)
&&
isScalarIntegerType
(
SrcTy
))
&&
"At most one of vmov's operands can be a core register."
);
return
isScalarIntegerType
(
DestTy
)
||
isScalarIntegerType
(
SrcTy
);
}
}
// end of anonymous namespace
}
// end of anonymous namespace
void
InstARM32Vmov
::
emitSingleDestSingleSource
(
const
Cfg
*
Func
)
const
{
void
InstARM32Vmov
::
emitSingleDestSingleSource
(
const
Cfg
*
Func
)
const
{
...
@@ -559,7 +575,14 @@ void InstARM32Vmov::emitSingleDestSingleSource(const Cfg *Func) const {
...
@@ -559,7 +575,14 @@ void InstARM32Vmov::emitSingleDestSingleSource(const Cfg *Func) const {
if
(
Dest
->
hasReg
())
{
if
(
Dest
->
hasReg
())
{
Operand
*
Src0
=
getSrc
(
0
);
Operand
*
Src0
=
getSrc
(
0
);
const
char
*
ActualOpcode
=
isMemoryAccess
(
Src0
)
?
"vldr"
:
"vmov"
;
const
char
*
ActualOpcode
=
isMemoryAccess
(
Src0
)
?
"vldr"
:
"vmov"
;
Str
<<
"
\t
"
<<
ActualOpcode
<<
"
\t
"
;
// when vmov{c}'ing, we need to emit a width string. Otherwise, the
// assembler might be tempted to assume we want a vector vmov{c}, and that
// is disallowed because ARM.
const
char
*
WidthString
=
(
isMemoryAccess
(
Src0
)
||
isMoveBetweenCoreAndVFPRegisters
(
Dest
,
Src0
))
?
""
:
getVecWidthString
(
Src0
->
getType
());
Str
<<
"
\t
"
<<
ActualOpcode
<<
getPredicate
()
<<
WidthString
<<
"
\t
"
;
Dest
->
emit
(
Func
);
Dest
->
emit
(
Func
);
Str
<<
", "
;
Str
<<
", "
;
Src0
->
emit
(
Func
);
Src0
->
emit
(
Func
);
...
@@ -567,8 +590,7 @@ void InstARM32Vmov::emitSingleDestSingleSource(const Cfg *Func) const {
...
@@ -567,8 +590,7 @@ void InstARM32Vmov::emitSingleDestSingleSource(const Cfg *Func) const {
Variable
*
Src0
=
llvm
::
cast
<
Variable
>
(
getSrc
(
0
));
Variable
*
Src0
=
llvm
::
cast
<
Variable
>
(
getSrc
(
0
));
assert
(
Src0
->
hasReg
());
assert
(
Src0
->
hasReg
());
Str
<<
"
\t
"
Str
<<
"
\t
"
"vstr"
"vstr"
<<
getPredicate
()
<<
"
\t
"
;
"
\t
"
;
Src0
->
emit
(
Func
);
Src0
->
emit
(
Func
);
Str
<<
", "
;
Str
<<
", "
;
Dest
->
emit
(
Func
);
Dest
->
emit
(
Func
);
...
@@ -578,7 +600,6 @@ void InstARM32Vmov::emitSingleDestSingleSource(const Cfg *Func) const {
...
@@ -578,7 +600,6 @@ void InstARM32Vmov::emitSingleDestSingleSource(const Cfg *Func) const {
void
InstARM32Vmov
::
emit
(
const
Cfg
*
Func
)
const
{
void
InstARM32Vmov
::
emit
(
const
Cfg
*
Func
)
const
{
if
(
!
BuildDefs
::
dump
())
if
(
!
BuildDefs
::
dump
())
return
;
return
;
assert
(
CondARM32
::
AL
==
getPredicate
());
assert
(
isMultiDest
()
+
isMultiSource
()
<=
1
&&
"Invalid vmov type."
);
assert
(
isMultiDest
()
+
isMultiSource
()
<=
1
&&
"Invalid vmov type."
);
if
(
isMultiDest
())
{
if
(
isMultiDest
())
{
emitMultiDestSingleSource
(
Func
);
emitMultiDestSingleSource
(
Func
);
...
@@ -1045,6 +1066,59 @@ void InstARM32Vcvt::dump(const Cfg *Func) const {
...
@@ -1045,6 +1066,59 @@ void InstARM32Vcvt::dump(const Cfg *Func) const {
dumpSources
(
Func
);
dumpSources
(
Func
);
}
}
void
InstARM32Vcmp
::
emit
(
const
Cfg
*
Func
)
const
{
if
(
!
BuildDefs
::
dump
())
return
;
Ostream
&
Str
=
Func
->
getContext
()
->
getStrEmit
();
assert
(
getSrcSize
()
==
2
);
Str
<<
"
\t
"
"vcmp"
<<
getPredicate
()
<<
getVecWidthString
(
getSrc
(
0
)
->
getType
())
<<
"
\t
"
;
getSrc
(
0
)
->
emit
(
Func
);
Str
<<
", "
;
getSrc
(
1
)
->
emit
(
Func
);
}
void
InstARM32Vcmp
::
emitIAS
(
const
Cfg
*
Func
)
const
{
assert
(
getSrcSize
()
==
2
);
(
void
)
Func
;
llvm_unreachable
(
"Not yet implemented"
);
}
void
InstARM32Vcmp
::
dump
(
const
Cfg
*
Func
)
const
{
if
(
!
BuildDefs
::
dump
())
return
;
Ostream
&
Str
=
Func
->
getContext
()
->
getStrDump
();
Str
<<
"vcmp"
<<
getPredicate
()
<<
getVecWidthString
(
getSrc
(
0
)
->
getType
());
dumpSources
(
Func
);
}
void
InstARM32Vmrs
::
emit
(
const
Cfg
*
Func
)
const
{
if
(
!
BuildDefs
::
dump
())
return
;
Ostream
&
Str
=
Func
->
getContext
()
->
getStrEmit
();
assert
(
getSrcSize
()
==
0
);
Str
<<
"
\t
"
"vmrs"
<<
getPredicate
()
<<
"
\t
"
"APSR_nzcv"
", "
"FPSCR"
;
}
void
InstARM32Vmrs
::
emitIAS
(
const
Cfg
*
Func
)
const
{
assert
(
getSrcSize
()
==
0
);
(
void
)
Func
;
llvm_unreachable
(
"Not yet implemented"
);
}
void
InstARM32Vmrs
::
dump
(
const
Cfg
*
Func
)
const
{
if
(
!
BuildDefs
::
dump
())
return
;
Ostream
&
Str
=
Func
->
getContext
()
->
getStrDump
();
Str
<<
"APSR{n,z,v,c} = vmrs"
<<
getPredicate
()
<<
"
\t
"
"FPSCR{n,z,c,v}"
;
}
void
OperandARM32Mem
::
emit
(
const
Cfg
*
Func
)
const
{
void
OperandARM32Mem
::
emit
(
const
Cfg
*
Func
)
const
{
if
(
!
BuildDefs
::
dump
())
if
(
!
BuildDefs
::
dump
())
return
;
return
;
...
...
src/IceInstARM32.h
View file @
2f5534f1
...
@@ -321,10 +321,12 @@ public:
...
@@ -321,10 +321,12 @@ public:
Umull
,
Umull
,
Uxt
,
Uxt
,
Vadd
,
Vadd
,
Vcmp
,
Vcvt
,
Vcvt
,
Vdiv
,
Vdiv
,
Vldr
,
Vldr
,
Vmov
,
Vmov
,
Vmrs
,
Vmul
,
Vmul
,
Vsqrt
,
Vsqrt
,
Vsub
Vsub
...
@@ -1204,6 +1206,46 @@ private:
...
@@ -1204,6 +1206,46 @@ private:
Variable
*
Dest1
=
nullptr
;
Variable
*
Dest1
=
nullptr
;
};
};
class
InstARM32Vcmp
final
:
public
InstARM32Pred
{
InstARM32Vcmp
()
=
delete
;
InstARM32Vcmp
(
const
InstARM32Vcmp
&
)
=
delete
;
InstARM32Vcmp
&
operator
=
(
const
InstARM32Vcmp
&
)
=
delete
;
public
:
static
InstARM32Vcmp
*
create
(
Cfg
*
Func
,
Variable
*
Src0
,
Variable
*
Src1
,
CondARM32
::
Cond
Predicate
)
{
return
new
(
Func
->
allocate
<
InstARM32Vcmp
>
())
InstARM32Vcmp
(
Func
,
Src0
,
Src1
,
Predicate
);
}
void
emit
(
const
Cfg
*
Func
)
const
override
;
void
emitIAS
(
const
Cfg
*
Func
)
const
override
;
void
dump
(
const
Cfg
*
Func
)
const
override
;
static
bool
classof
(
const
Inst
*
Inst
)
{
return
isClassof
(
Inst
,
Vcmp
);
}
private
:
InstARM32Vcmp
(
Cfg
*
Func
,
Variable
*
Src0
,
Variable
*
Src1
,
CondARM32
::
Cond
Predicate
);
};
/// Copies the FP Status and Control Register the core flags.
class
InstARM32Vmrs
final
:
public
InstARM32Pred
{
InstARM32Vmrs
()
=
delete
;
InstARM32Vmrs
(
const
InstARM32Vmrs
&
)
=
delete
;
InstARM32Vmrs
&
operator
=
(
const
InstARM32Vmrs
&
)
=
delete
;
public
:
static
InstARM32Vmrs
*
create
(
Cfg
*
Func
,
CondARM32
::
Cond
Predicate
)
{
return
new
(
Func
->
allocate
<
InstARM32Vmrs
>
())
InstARM32Vmrs
(
Func
,
Predicate
);
}
void
emit
(
const
Cfg
*
Func
)
const
override
;
void
emitIAS
(
const
Cfg
*
Func
)
const
override
;
void
dump
(
const
Cfg
*
Func
)
const
override
;
static
bool
classof
(
const
Inst
*
Inst
)
{
return
isClassof
(
Inst
,
Vmrs
);
}
private
:
InstARM32Vmrs
(
Cfg
*
Func
,
CondARM32
::
Cond
Predicate
);
};
// Declare partial template specializations of emit() methods that already have
// Declare partial template specializations of emit() methods that already have
// default implementations. Without this, there is the possibility of ODR
// default implementations. Without this, there is the possibility of ODR
// violations and link errors.
// violations and link errors.
...
...
src/IceTargetLoweringARM32.cpp
View file @
2f5534f1
...
@@ -87,40 +87,39 @@ CondARM32::Cond getIcmp32Mapping(InstIcmp::ICond Cond) {
...
@@ -87,40 +87,39 @@ CondARM32::Cond getIcmp32Mapping(InstIcmp::ICond Cond) {
// instructions/operands that use the same enum key value. The tables are kept
// instructions/operands that use the same enum key value. The tables are kept
// separate to maintain a proper separation between abstraction layers. There
// separate to maintain a proper separation between abstraction layers. There
// is a risk that the tables could get out of sync if enum values are reordered
// is a risk that the tables could get out of sync if enum values are reordered
// or if entries are added or deleted. The following
dummy
namespaces use
// or if entries are added or deleted. The following
anonymous
namespaces use
// static_asserts to ensure everything is kept in sync.
// static_asserts to ensure everything is kept in sync.
// Validate the enum values in ICMPARM32_TABLE.
// Validate the enum values in ICMPARM32_TABLE.
namespace
dummy1
{
namespace
{
// Define a temporary set of enum values based on low-level table entries.
// Define a temporary set of enum values based on low-level table entries.
enum
_
tmp
_enum
{
enum
_
icmp_ll
_enum
{
#define X(val, signed, swapped64, C_32, C1_64, C2_64) _
tmp
_##val,
#define X(val, signed, swapped64, C_32, C1_64, C2_64) _
icmp_ll
_##val,
ICMPARM32_TABLE
ICMPARM32_TABLE
#undef X
#undef X
_num
_num
};
};
// Define a set of constants based on high-level table entries.
// Define a set of constants based on high-level table entries.
#define X(tag, str) static const
int _table1
_##tag = InstIcmp::tag;
#define X(tag, str) static const
expr int _icmp_hl
_##tag = InstIcmp::tag;
ICEINSTICMP_TABLE
ICEINSTICMP_TABLE
#undef X
#undef X
// Define a set of constants based on low-level table entries, and ensure the
// Define a set of constants based on low-level table entries, and ensure the
// table entry keys are consistent.
// table entry keys are consistent.
#define X(val, signed, swapped64, C_32, C1_64, C2_64) \
#define X(val, signed, swapped64, C_32, C1_64, C2_64) \
static const int _table2_##val = _tmp_##val; \
static_assert( \
static_assert( \
_
table1_##val == _table2_##val,
\
_
icmp_ll_##val == _icmp_hl_##val,
\
"Inconsistency between ICMPARM32_TABLE and ICEINSTICMP_TABLE
"
);
"Inconsistency between ICMPARM32_TABLE and ICEINSTICMP_TABLE
: " #val
);
ICMPARM32_TABLE
ICMPARM32_TABLE
#undef X
#undef X
// Repeat the static asserts with respect to the high-level table entries in
// Repeat the static asserts with respect to the high-level table entries in
// case the high-level table has extra entries.
// case the high-level table has extra entries.
#define X(tag, str) \
#define X(tag, str) \
static_assert( \
static_assert( \
_
table1_##tag == _table2_##tag,
\
_
icmp_hl_##tag == _icmp_ll_##tag,
\
"Inconsistency between ICMPARM32_TABLE and ICEINSTICMP_TABLE
"
);
"Inconsistency between ICMPARM32_TABLE and ICEINSTICMP_TABLE
: " #tag
);
ICEINSTICMP_TABLE
ICEINSTICMP_TABLE
#undef X
#undef X
}
// end of
namespace dummy1
}
// end of
anonymous namespace
// Stack alignment
// Stack alignment
const
uint32_t
ARM32_STACK_ALIGNMENT_BYTES
=
16
;
const
uint32_t
ARM32_STACK_ALIGNMENT_BYTES
=
16
;
...
@@ -2229,9 +2228,76 @@ void TargetARM32::lowerExtractElement(const InstExtractElement *Inst) {
...
@@ -2229,9 +2228,76 @@ void TargetARM32::lowerExtractElement(const InstExtractElement *Inst) {
UnimplementedError
(
Func
->
getContext
()
->
getFlags
());
UnimplementedError
(
Func
->
getContext
()
->
getFlags
());
}
}
namespace
{
// Validates FCMPARM32_TABLE's declaration w.r.t. InstFcmp::FCondition ordering
// (and naming).
enum
{
#define X(val, CC0, CC1) _fcmp_ll_##val,
FCMPARM32_TABLE
#undef X
_fcmp_ll_NUM
};
enum
{
#define X(tag, str) _fcmp_hl_##tag = InstFcmp::tag,
ICEINSTFCMP_TABLE
#undef X
_fcmp_hl_NUM
};
static_assert
(
_fcmp_hl_NUM
==
_fcmp_ll_NUM
,
"Inconsistency between high-level and low-level fcmp tags."
);
#define X(tag, str) \
static_assert( \
_fcmp_hl_##tag == _fcmp_ll_##tag, \
"Inconsistency between high-level and low-level fcmp tag " #tag);
ICEINSTFCMP_TABLE
#undef X
struct
{
CondARM32
::
Cond
CC0
;
CondARM32
::
Cond
CC1
;
}
TableFcmp
[]
=
{
#define X(val, CC0, CC1) \
{ CondARM32::CC0, CondARM32::CC1 } \
,
FCMPARM32_TABLE
#undef X
};
}
// end of anonymous namespace
void
TargetARM32
::
lowerFcmp
(
const
InstFcmp
*
Inst
)
{
void
TargetARM32
::
lowerFcmp
(
const
InstFcmp
*
Inst
)
{
(
void
)
Inst
;
Variable
*
Dest
=
Inst
->
getDest
();
UnimplementedError
(
Func
->
getContext
()
->
getFlags
());
if
(
isVectorType
(
Dest
->
getType
()))
{
UnimplementedError
(
Func
->
getContext
()
->
getFlags
());
return
;
}
Variable
*
Src0R
=
legalizeToReg
(
Inst
->
getSrc
(
0
));
Variable
*
Src1R
=
legalizeToReg
(
Inst
->
getSrc
(
1
));
Variable
*
T
=
makeReg
(
IceType_i32
);
_vcmp
(
Src0R
,
Src1R
);
_mov
(
T
,
Ctx
->
getConstantZero
(
IceType_i32
));
_vmrs
();
Operand
*
One
=
Ctx
->
getConstantInt32
(
1
);
InstFcmp
::
FCond
Condition
=
Inst
->
getCondition
();
assert
(
Condition
<
llvm
::
array_lengthof
(
TableFcmp
));
CondARM32
::
Cond
CC0
=
TableFcmp
[
Condition
].
CC0
;
CondARM32
::
Cond
CC1
=
TableFcmp
[
Condition
].
CC1
;
if
(
CC0
!=
CondARM32
::
kNone
)
{
_mov
(
T
,
One
,
CC0
);
// If this mov is not a maybe mov, but an actual mov (i.e., CC0 == AL), we
// don't want to set_dest_nonkillable so that liveness + dead-code
// elimination will get rid of the previous assignment (i.e., T = 0) above.
if
(
CC0
!=
CondARM32
::
AL
)
_set_dest_nonkillable
();
}
if
(
CC1
!=
CondARM32
::
kNone
)
{
assert
(
CC0
!=
CondARM32
::
kNone
);
assert
(
CC1
!=
CondARM32
::
AL
);
_mov_nonkillable
(
T
,
One
,
CC1
);
}
_mov
(
Dest
,
T
);
}
}
void
TargetARM32
::
lowerIcmp
(
const
InstIcmp
*
Inst
)
{
void
TargetARM32
::
lowerIcmp
(
const
InstIcmp
*
Inst
)
{
...
@@ -2695,16 +2761,12 @@ void TargetARM32::lowerSelect(const InstSelect *Inst) {
...
@@ -2695,16 +2761,12 @@ void TargetARM32::lowerSelect(const InstSelect *Inst) {
UnimplementedError
(
Func
->
getContext
()
->
getFlags
());
UnimplementedError
(
Func
->
getContext
()
->
getFlags
());
return
;
return
;
}
}
if
(
isFloatingType
(
DestTy
))
{
UnimplementedError
(
Func
->
getContext
()
->
getFlags
());
return
;
}
// TODO(jvoung): handle folding opportunities.
// TODO(jvoung): handle folding opportunities.
// cmp cond, #0; mov t, SrcF; mov_cond t, SrcT; mov dest, t
// cmp cond, #0; mov t, SrcF; mov_cond t, SrcT; mov dest, t
Variable
*
CmpOpnd0
=
legalizeToReg
(
Condition
);
Variable
*
CmpOpnd0
=
legalizeToReg
(
Condition
);
Operand
*
CmpOpnd1
=
Ctx
->
getConstantZero
(
IceType_i32
);
Operand
*
CmpOpnd1
=
Ctx
->
getConstantZero
(
IceType_i32
);
_cmp
(
CmpOpnd0
,
CmpOpnd1
);
_cmp
(
CmpOpnd0
,
CmpOpnd1
);
CondARM32
::
Cond
Cond
=
CondARM32
::
NE
;
static
constexpr
CondARM32
::
Cond
Cond
=
CondARM32
::
NE
;
if
(
DestTy
==
IceType_i64
)
{
if
(
DestTy
==
IceType_i64
)
{
SrcT
=
legalizeUndef
(
SrcT
);
SrcT
=
legalizeUndef
(
SrcT
);
SrcF
=
legalizeUndef
(
SrcF
);
SrcF
=
legalizeUndef
(
SrcF
);
...
@@ -2726,6 +2788,20 @@ void TargetARM32::lowerSelect(const InstSelect *Inst) {
...
@@ -2726,6 +2788,20 @@ void TargetARM32::lowerSelect(const InstSelect *Inst) {
_mov
(
DestHi
,
THi
);
_mov
(
DestHi
,
THi
);
return
;
return
;
}
}
if
(
isFloatingType
(
DestTy
))
{
Variable
*
T
=
makeReg
(
DestTy
);
SrcF
=
legalizeToReg
(
SrcF
);
assert
(
DestTy
==
SrcF
->
getType
());
_vmov
(
T
,
SrcF
);
SrcT
=
legalizeToReg
(
SrcT
);
assert
(
DestTy
==
SrcT
->
getType
());
_vmov
(
T
,
SrcT
,
Cond
);
_set_dest_nonkillable
();
_vmov
(
Dest
,
T
);
return
;
}
Variable
*
T
=
nullptr
;
Variable
*
T
=
nullptr
;
SrcF
=
legalize
(
SrcF
,
Legal_Reg
|
Legal_Flex
);
SrcF
=
legalize
(
SrcF
,
Legal_Reg
|
Legal_Flex
);
_mov
(
T
,
SrcF
);
_mov
(
T
,
SrcF
);
...
...
src/IceTargetLoweringARM32.def
View file @
2f5534f1
...
@@ -15,19 +15,47 @@
...
@@ -15,19 +15,47 @@
#ifndef SUBZERO_SRC_ICETARGETLOWERINGARM32_DEF
#ifndef SUBZERO_SRC_ICETARGETLOWERINGARM32_DEF
#define SUBZERO_SRC_ICETARGETLOWERINGARM32_DEF
#define SUBZERO_SRC_ICETARGETLOWERINGARM32_DEF
// Patterns for lowering fcmp. These are expected to be used in the following
// manner:
//
// mov reg, #0
// movCC0 reg, #1 /* only if CC0 != kNone */
// movCC1 reg, #1 /* only if CC1 != kNone */
//
// TODO(jpp): vector lowerings.
#define FCMPARM32_TABLE \
/* val, CC0, CC1 */ \
X(False, kNone, kNone) \
X(Oeq, EQ, kNone) \
X(Ogt, GT, kNone) \
X(Oge, GE, kNone) \
X(Olt, MI, kNone) \
X(Ole, LS, kNone) \
X(One, MI, GT) \
X(Ord, VC, kNone) \
X(Ueq, EQ, VS) \
X(Ugt, HI, kNone) \
X(Uge, PL, kNone) \
X(Ult, LT, kNone) \
X(Ule, LE, kNone) \
X(Une, NE, kNone) \
X(Uno, VS, kNone) \
X(True, AL, kNone) \
//#define X(val, CC0, CC1)
// Patterns for lowering icmp.
// Patterns for lowering icmp.
#define ICMPARM32_TABLE \
#define ICMPARM32_TABLE
\
/* val, is_signed, swapped64, C_32, C1_64, C2_64 */ \
/* val, is_signed, swapped64, C_32, C1_64, C2_64 */
\
X(Eq, false, false, EQ, EQ, NE) \
X(Eq, false, false, EQ, EQ, NE)
\
X(Ne, false, false, NE, NE, EQ) \
X(Ne, false, false, NE, NE, EQ)
\
X(Ugt, false, false, HI, HI, LS) \
X(Ugt, false, false, HI, HI, LS)
\
X(Uge, false, false, CS, CS, CC) \
X(Uge, false, false, CS, CS, CC)
\
X(Ult, false, false, CC, CC, CS) \
X(Ult, false, false, CC, CC, CS)
\
X(Ule, false, false, LS, LS, HI) \
X(Ule, false, false, LS, LS, HI)
\
X(Sgt, true, true, GT, LT, GE) \
X(Sgt, true, true, GT, LT, GE)
\
X(Sge, true, false, GE, GE, LT) \
X(Sge, true, false, GE, GE, LT)
\
X(Slt, true, false, LT, LT, GE) \
X(Slt, true, false, LT, LT, GE)
\
X(Sle, true, true, LE, GE, LT) \
X(Sle, true, true, LE, GE, LT)
\
//#define X(val, is_signed, swapped64, C_32, C1_64, C2_64)
//#define X(val, is_signed, swapped64, C_32, C1_64, C2_64)
#endif // SUBZERO_SRC_ICETARGETLOWERINGARM32_DEF
#endif // SUBZERO_SRC_ICETARGETLOWERINGARM32_DEF
src/IceTargetLoweringARM32.h
View file @
2f5534f1
...
@@ -401,6 +401,13 @@ protected:
...
@@ -401,6 +401,13 @@ protected:
CondARM32
::
Cond
Pred
=
CondARM32
::
AL
)
{
CondARM32
::
Cond
Pred
=
CondARM32
::
AL
)
{
Context
.
insert
(
InstARM32Vldr
::
create
(
Func
,
Dest
,
Src
,
Pred
));
Context
.
insert
(
InstARM32Vldr
::
create
(
Func
,
Dest
,
Src
,
Pred
));
}
}
void
_vcmp
(
Variable
*
Src0
,
Variable
*
Src1
,
CondARM32
::
Cond
Pred
=
CondARM32
::
AL
)
{
Context
.
insert
(
InstARM32Vcmp
::
create
(
Func
,
Src0
,
Src1
,
Pred
));
}
void
_vmrs
(
CondARM32
::
Cond
Pred
=
CondARM32
::
AL
)
{
Context
.
insert
(
InstARM32Vmrs
::
create
(
Func
,
Pred
));
}
// There are a whole bunch of vmov variants, to transfer within S/D/Q
// There are a whole bunch of vmov variants, to transfer within S/D/Q
// registers, between core integer registers and S/D, and from small
// registers, between core integer registers and S/D, and from small
// immediates into S/D. For integer -> S/D/Q there is a variant which takes
// immediates into S/D. For integer -> S/D/Q there is a variant which takes
...
@@ -411,8 +418,8 @@ protected:
...
@@ -411,8 +418,8 @@ protected:
// register is modified. This cannot model that.
// register is modified. This cannot model that.
//
//
// This represents the simple single source, single dest variants only.
// This represents the simple single source, single dest variants only.
void
_vmov
(
Variable
*
Dest
,
Operand
*
Src0
)
{
void
_vmov
(
Variable
*
Dest
,
Operand
*
Src0
,
constexpr
CondARM32
::
Cond
Pred
=
CondARM32
::
AL
;
CondARM32
::
Cond
Pred
=
CondARM32
::
AL
)
{
Context
.
insert
(
InstARM32Vmov
::
create
(
Func
,
Dest
,
Src0
,
Pred
));
Context
.
insert
(
InstARM32Vmov
::
create
(
Func
,
Dest
,
Src0
,
Pred
));
}
}
// This represents the single source, multi dest variant.
// This represents the single source, multi dest variant.
...
...
tests_lit/llvm2ice_tests/fp.cmp.ll
View file @
2f5534f1
...
@@ -6,6 +6,16 @@
...
@@ -6,6 +6,16 @@
; RUN: %p2i --filetype=obj --disassemble -i %s --args -O2 | FileCheck %s
; RUN: %p2i --filetype=obj --disassemble -i %s --args -O2 | FileCheck %s
; RUN: %p2i --filetype=obj --disassemble -i %s --args -Om1 | FileCheck %s
; RUN: %p2i --filetype=obj --disassemble -i %s --args -Om1 | FileCheck %s
; RUN: %if --need=allow_dump --need=target_ARM32 --command %p2i --filetype=asm \
; RUN: --target arm32 -i %s --args -O2 --skip-unimplemented \
; RUN: | %if --need=allow_dump --need=target_ARM32 --command FileCheck %s \
; RUN: --check-prefix=ARM32
; RUN: %if --need=allow_dump --need=target_ARM32 --command %p2i --filetype=asm \
; RUN: --target arm32 -i %s --args -Om1 --skip-unimplemented \
; RUN: | %if --need=allow_dump --need=target_ARM32 --command FileCheck %s \
; RUN: --check-prefix=ARM32
define
internal
void
@fcmpEq
(
float
%a
,
float
%b
,
double
%c
,
double
%d
)
{
define
internal
void
@fcmpEq
(
float
%a
,
float
%b
,
double
%c
,
double
%d
)
{
entry:
entry:
%cmp
=
fcmp
oeq
float
%a
,
%b
%cmp
=
fcmp
oeq
float
%a
,
%b
...
@@ -35,6 +45,15 @@ if.end3: ; preds = %if.then2, %if.end
...
@@ -35,6 +45,15 @@ if.end3: ; preds = %if.then2, %if.end
; CHECK: jne
; CHECK: jne
; CHECK-NEXT: jp
; CHECK-NEXT: jp
; CHECK: call {{.*}} R_{{.*}} func
; CHECK: call {{.*}} R_{{.*}} func
; ARM32-LABEL: fcmpEq
; ARM32: vcmp.f32
; ARM32: mov [[R0:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: moveq [[R0]], #1
; ARM32: vcmp.f64
; ARM32: mov [[R1:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: moveq [[R1]], #1
declare
void
@func
()
declare
void
@func
()
...
@@ -67,6 +86,15 @@ if.end3: ; preds = %if.then2, %if.end
...
@@ -67,6 +86,15 @@ if.end3: ; preds = %if.then2, %if.end
; CHECK: jne
; CHECK: jne
; CHECK-NEXT: jp
; CHECK-NEXT: jp
; CHECK: call {{.*}} R_{{.*}} func
; CHECK: call {{.*}} R_{{.*}} func
; ARM32-LABEL: fcmpNe
; ARM32: vcmp.f32
; ARM32: mov [[R0:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: movne [[R0]], #1
; ARM32: vcmp.f64
; ARM32: mov [[R1:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: movne [[R1]], #1
define
internal
void
@fcmpGt
(
float
%a
,
float
%b
,
double
%c
,
double
%d
)
{
define
internal
void
@fcmpGt
(
float
%a
,
float
%b
,
double
%c
,
double
%d
)
{
entry:
entry:
...
@@ -95,6 +123,15 @@ if.end3: ; preds = %if.then2, %if.end
...
@@ -95,6 +123,15 @@ if.end3: ; preds = %if.then2, %if.end
; CHECK: ucomisd
; CHECK: ucomisd
; CHECK: seta
; CHECK: seta
; CHECK: call {{.*}} R_{{.*}} func
; CHECK: call {{.*}} R_{{.*}} func
; ARM32-LABEL: fcmpGt
; ARM32: vcmp.f32
; ARM32: mov [[R0:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: movgt [[R0]], #1
; ARM32: vcmp.f64
; ARM32: mov [[R1:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: movgt [[R1]], #1
define
internal
void
@fcmpGe
(
float
%a
,
float
%b
,
double
%c
,
double
%d
)
{
define
internal
void
@fcmpGe
(
float
%a
,
float
%b
,
double
%c
,
double
%d
)
{
entry:
entry:
...
@@ -123,6 +160,15 @@ if.end3: ; preds = %if.end, %if.then2
...
@@ -123,6 +160,15 @@ if.end3: ; preds = %if.end, %if.then2
; CHECK: ucomisd
; CHECK: ucomisd
; CHECK: setb
; CHECK: setb
; CHECK: call {{.*}} R_{{.*}} func
; CHECK: call {{.*}} R_{{.*}} func
; ARM32-LABEL: fcmpGe
; ARM32: vcmp.f32
; ARM32: mov [[R0:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: movlt [[R0]], #1
; ARM32: vcmp.f64
; ARM32: mov [[R1:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: movlt [[R1]], #1
define
internal
void
@fcmpLt
(
float
%a
,
float
%b
,
double
%c
,
double
%d
)
{
define
internal
void
@fcmpLt
(
float
%a
,
float
%b
,
double
%c
,
double
%d
)
{
entry:
entry:
...
@@ -151,6 +197,15 @@ if.end3: ; preds = %if.then2, %if.end
...
@@ -151,6 +197,15 @@ if.end3: ; preds = %if.then2, %if.end
; CHECK: ucomisd
; CHECK: ucomisd
; CHECK: seta
; CHECK: seta
; CHECK: call {{.*}} R_{{.*}} func
; CHECK: call {{.*}} R_{{.*}} func
; ARM32-LABEL: fcmpLt
; ARM32: vcmp.f32
; ARM32: mov [[R0:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: movmi [[R0]], #1
; ARM32: vcmp.f64
; ARM32: mov [[R1:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: movmi [[R1]], #1
define
internal
void
@fcmpLe
(
float
%a
,
float
%b
,
double
%c
,
double
%d
)
{
define
internal
void
@fcmpLe
(
float
%a
,
float
%b
,
double
%c
,
double
%d
)
{
entry:
entry:
...
@@ -179,6 +234,15 @@ if.end3: ; preds = %if.end, %if.then2
...
@@ -179,6 +234,15 @@ if.end3: ; preds = %if.end, %if.then2
; CHECK: ucomisd
; CHECK: ucomisd
; CHECK: setb
; CHECK: setb
; CHECK: call {{.*}} R_{{.*}} func
; CHECK: call {{.*}} R_{{.*}} func
; ARM32-LABEL: fcmpLe
; ARM32: vcmp.f32
; ARM32: mov [[R0:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: movhi [[R0]], #1
; ARM32: vcmp.f64
; ARM32: mov [[R1:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: movhi [[R1]], #1
define
internal
i32
@fcmpFalseFloat
(
float
%a
,
float
%b
)
{
define
internal
i32
@fcmpFalseFloat
(
float
%a
,
float
%b
)
{
entry:
entry:
...
@@ -188,6 +252,9 @@ entry:
...
@@ -188,6 +252,9 @@ entry:
}
}
; CHECK-LABEL: fcmpFalseFloat
; CHECK-LABEL: fcmpFalseFloat
; CHECK: mov {{.*}},0x0
; CHECK: mov {{.*}},0x0
; ARM32-LABEL: fcmpFalseFloat
; ARM32: vcmp.f32
; ARM32: mov [[R:r[0-9]+]], #0
define
internal
i32
@fcmpFalseDouble
(
double
%a
,
double
%b
)
{
define
internal
i32
@fcmpFalseDouble
(
double
%a
,
double
%b
)
{
entry:
entry:
...
@@ -197,6 +264,9 @@ entry:
...
@@ -197,6 +264,9 @@ entry:
}
}
; CHECK-LABEL: fcmpFalseDouble
; CHECK-LABEL: fcmpFalseDouble
; CHECK: mov {{.*}},0x0
; CHECK: mov {{.*}},0x0
; ARM32-LABEL: fcmpFalseDouble
; ARM32: vcmp.f64
; ARM32: mov [[R:r[0-9]+]], #0
define
internal
i32
@fcmpOeqFloat
(
float
%a
,
float
%b
)
{
define
internal
i32
@fcmpOeqFloat
(
float
%a
,
float
%b
)
{
entry:
entry:
...
@@ -208,6 +278,11 @@ entry:
...
@@ -208,6 +278,11 @@ entry:
; CHECK: ucomiss
; CHECK: ucomiss
; CHECK: jne
; CHECK: jne
; CHECK: jp
; CHECK: jp
; ARM32-LABEL: fcmpOeqFloat
; ARM32: vcmp.f32
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: moveq [[R]], #1
define
internal
i32
@fcmpOeqDouble
(
double
%a
,
double
%b
)
{
define
internal
i32
@fcmpOeqDouble
(
double
%a
,
double
%b
)
{
entry:
entry:
...
@@ -219,6 +294,11 @@ entry:
...
@@ -219,6 +294,11 @@ entry:
; CHECK: ucomisd
; CHECK: ucomisd
; CHECK: jne
; CHECK: jne
; CHECK: jp
; CHECK: jp
; ARM32-LABEL: fcmpOeqDouble
; ARM32: vcmp.f64
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: moveq [[R]], #1
define
internal
i32
@fcmpOgtFloat
(
float
%a
,
float
%b
)
{
define
internal
i32
@fcmpOgtFloat
(
float
%a
,
float
%b
)
{
entry:
entry:
...
@@ -229,6 +309,11 @@ entry:
...
@@ -229,6 +309,11 @@ entry:
; CHECK-LABEL: fcmpOgtFloat
; CHECK-LABEL: fcmpOgtFloat
; CHECK: ucomiss
; CHECK: ucomiss
; CHECK: seta
; CHECK: seta
; ARM32-LABEL: fcmpOgtFloat
; ARM32: vcmp.f32
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: movgt [[R]], #1
define
internal
i32
@fcmpOgtDouble
(
double
%a
,
double
%b
)
{
define
internal
i32
@fcmpOgtDouble
(
double
%a
,
double
%b
)
{
entry:
entry:
...
@@ -239,6 +324,11 @@ entry:
...
@@ -239,6 +324,11 @@ entry:
; CHECK-LABEL: fcmpOgtDouble
; CHECK-LABEL: fcmpOgtDouble
; CHECK: ucomisd
; CHECK: ucomisd
; CHECK: seta
; CHECK: seta
; ARM32-LABEL: fcmpOgtDouble
; ARM32: vcmp.f64
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: movgt [[R]], #1
define
internal
i32
@fcmpOgeFloat
(
float
%a
,
float
%b
)
{
define
internal
i32
@fcmpOgeFloat
(
float
%a
,
float
%b
)
{
entry:
entry:
...
@@ -249,6 +339,11 @@ entry:
...
@@ -249,6 +339,11 @@ entry:
; CHECK-LABEL: fcmpOgeFloat
; CHECK-LABEL: fcmpOgeFloat
; CHECK: ucomiss
; CHECK: ucomiss
; CHECK: setae
; CHECK: setae
; ARM32-LABEL: fcmpOgeFloat
; ARM32: vcmp.f32
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: movge [[R]], #1
define
internal
i32
@fcmpOgeDouble
(
double
%a
,
double
%b
)
{
define
internal
i32
@fcmpOgeDouble
(
double
%a
,
double
%b
)
{
entry:
entry:
...
@@ -259,6 +354,11 @@ entry:
...
@@ -259,6 +354,11 @@ entry:
; CHECK-LABEL: fcmpOgeDouble
; CHECK-LABEL: fcmpOgeDouble
; CHECK: ucomisd
; CHECK: ucomisd
; CHECK: setae
; CHECK: setae
; ARM32-LABEL: fcmpOgeDouble
; ARM32: vcmp.f64
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: movge [[R]], #1
define
internal
i32
@fcmpOltFloat
(
float
%a
,
float
%b
)
{
define
internal
i32
@fcmpOltFloat
(
float
%a
,
float
%b
)
{
entry:
entry:
...
@@ -269,6 +369,11 @@ entry:
...
@@ -269,6 +369,11 @@ entry:
; CHECK-LABEL: fcmpOltFloat
; CHECK-LABEL: fcmpOltFloat
; CHECK: ucomiss
; CHECK: ucomiss
; CHECK: seta
; CHECK: seta
; ARM32-LABEL: fcmpOltFloat
; ARM32: vcmp.f32
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: movmi [[R]], #1
define
internal
i32
@fcmpOltDouble
(
double
%a
,
double
%b
)
{
define
internal
i32
@fcmpOltDouble
(
double
%a
,
double
%b
)
{
entry:
entry:
...
@@ -279,6 +384,11 @@ entry:
...
@@ -279,6 +384,11 @@ entry:
; CHECK-LABEL: fcmpOltDouble
; CHECK-LABEL: fcmpOltDouble
; CHECK: ucomisd
; CHECK: ucomisd
; CHECK: seta
; CHECK: seta
; ARM32-LABEL: fcmpOltDouble
; ARM32: vcmp.f64
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: movmi [[R]], #1
define
internal
i32
@fcmpOleFloat
(
float
%a
,
float
%b
)
{
define
internal
i32
@fcmpOleFloat
(
float
%a
,
float
%b
)
{
entry:
entry:
...
@@ -289,6 +399,11 @@ entry:
...
@@ -289,6 +399,11 @@ entry:
; CHECK-LABEL: fcmpOleFloat
; CHECK-LABEL: fcmpOleFloat
; CHECK: ucomiss
; CHECK: ucomiss
; CHECK: setae
; CHECK: setae
; ARM32-LABEL: fcmpOleFloat
; ARM32: vcmp.f32
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: movls [[R]], #1
define
internal
i32
@fcmpOleDouble
(
double
%a
,
double
%b
)
{
define
internal
i32
@fcmpOleDouble
(
double
%a
,
double
%b
)
{
entry:
entry:
...
@@ -299,6 +414,11 @@ entry:
...
@@ -299,6 +414,11 @@ entry:
; CHECK-LABEL: fcmpOleDouble
; CHECK-LABEL: fcmpOleDouble
; CHECK: ucomisd
; CHECK: ucomisd
; CHECK: setae
; CHECK: setae
; ARM32-LABEL: fcmpOleDouble
; ARM32: vcmp.f64
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: movls [[R]], #1
define
internal
i32
@fcmpOneFloat
(
float
%a
,
float
%b
)
{
define
internal
i32
@fcmpOneFloat
(
float
%a
,
float
%b
)
{
entry:
entry:
...
@@ -309,6 +429,12 @@ entry:
...
@@ -309,6 +429,12 @@ entry:
; CHECK-LABEL: fcmpOneFloat
; CHECK-LABEL: fcmpOneFloat
; CHECK: ucomiss
; CHECK: ucomiss
; CHECK: setne
; CHECK: setne
; ARM32-LABEL: fcmpOneFloat
; ARM32: vcmp.f32
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: movmi [[R]], #1
; ARM32: movgt [[R]], #1
define
internal
i32
@fcmpOneDouble
(
double
%a
,
double
%b
)
{
define
internal
i32
@fcmpOneDouble
(
double
%a
,
double
%b
)
{
entry:
entry:
...
@@ -319,6 +445,12 @@ entry:
...
@@ -319,6 +445,12 @@ entry:
; CHECK-LABEL: fcmpOneDouble
; CHECK-LABEL: fcmpOneDouble
; CHECK: ucomisd
; CHECK: ucomisd
; CHECK: setne
; CHECK: setne
; ARM32-LABEL: fcmpOneDouble
; ARM32: vcmp.f64
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: movmi [[R]], #1
; ARM32: movgt [[R]], #1
define
internal
i32
@fcmpOrdFloat
(
float
%a
,
float
%b
)
{
define
internal
i32
@fcmpOrdFloat
(
float
%a
,
float
%b
)
{
entry:
entry:
...
@@ -329,6 +461,11 @@ entry:
...
@@ -329,6 +461,11 @@ entry:
; CHECK-LABEL: fcmpOrdFloat
; CHECK-LABEL: fcmpOrdFloat
; CHECK: ucomiss
; CHECK: ucomiss
; CHECK: setnp
; CHECK: setnp
; ARM32-LABEL: fcmpOrdFloat
; ARM32: vcmp.f32
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: movvc [[R]], #1
define
internal
i32
@fcmpOrdDouble
(
double
%a
,
double
%b
)
{
define
internal
i32
@fcmpOrdDouble
(
double
%a
,
double
%b
)
{
entry:
entry:
...
@@ -339,6 +476,11 @@ entry:
...
@@ -339,6 +476,11 @@ entry:
; CHECK-LABEL: fcmpOrdDouble
; CHECK-LABEL: fcmpOrdDouble
; CHECK: ucomisd
; CHECK: ucomisd
; CHECK: setnp
; CHECK: setnp
; ARM32-LABEL: fcmpOrdDouble
; ARM32: vcmp.f64
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: movvc [[R]], #1
define
internal
i32
@fcmpUeqFloat
(
float
%a
,
float
%b
)
{
define
internal
i32
@fcmpUeqFloat
(
float
%a
,
float
%b
)
{
entry:
entry:
...
@@ -349,6 +491,12 @@ entry:
...
@@ -349,6 +491,12 @@ entry:
; CHECK-LABEL: fcmpUeqFloat
; CHECK-LABEL: fcmpUeqFloat
; CHECK: ucomiss
; CHECK: ucomiss
; CHECK: sete
; CHECK: sete
; ARM32-LABEL: fcmpUeqFloat
; ARM32: vcmp.f32
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: moveq [[R]], #1
; ARM32: movvs [[R]], #1
define
internal
i32
@fcmpUeqDouble
(
double
%a
,
double
%b
)
{
define
internal
i32
@fcmpUeqDouble
(
double
%a
,
double
%b
)
{
entry:
entry:
...
@@ -359,6 +507,12 @@ entry:
...
@@ -359,6 +507,12 @@ entry:
; CHECK-LABEL: fcmpUeqDouble
; CHECK-LABEL: fcmpUeqDouble
; CHECK: ucomisd
; CHECK: ucomisd
; CHECK: sete
; CHECK: sete
; ARM32-LABEL: fcmpUeqDouble
; ARM32: vcmp.f64
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: moveq [[R]], #1
; ARM32: movvs [[R]], #1
define
internal
i32
@fcmpUgtFloat
(
float
%a
,
float
%b
)
{
define
internal
i32
@fcmpUgtFloat
(
float
%a
,
float
%b
)
{
entry:
entry:
...
@@ -369,6 +523,11 @@ entry:
...
@@ -369,6 +523,11 @@ entry:
; CHECK-LABEL: fcmpUgtFloat
; CHECK-LABEL: fcmpUgtFloat
; CHECK: ucomiss
; CHECK: ucomiss
; CHECK: setb
; CHECK: setb
; ARM32-LABEL: fcmpUgtFloat
; ARM32: vcmp.f32
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: movhi [[R]], #1
define
internal
i32
@fcmpUgtDouble
(
double
%a
,
double
%b
)
{
define
internal
i32
@fcmpUgtDouble
(
double
%a
,
double
%b
)
{
entry:
entry:
...
@@ -379,6 +538,11 @@ entry:
...
@@ -379,6 +538,11 @@ entry:
; CHECK-LABEL: fcmpUgtDouble
; CHECK-LABEL: fcmpUgtDouble
; CHECK: ucomisd
; CHECK: ucomisd
; CHECK: setb
; CHECK: setb
; ARM32-LABEL: fcmpUgtDouble
; ARM32: vcmp.f64
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: movhi [[R]], #1
define
internal
i32
@fcmpUgeFloat
(
float
%a
,
float
%b
)
{
define
internal
i32
@fcmpUgeFloat
(
float
%a
,
float
%b
)
{
entry:
entry:
...
@@ -389,6 +553,11 @@ entry:
...
@@ -389,6 +553,11 @@ entry:
; CHECK-LABEL: fcmpUgeFloat
; CHECK-LABEL: fcmpUgeFloat
; CHECK: ucomiss
; CHECK: ucomiss
; CHECK: setbe
; CHECK: setbe
; ARM32-LABEL: fcmpUgeFloat
; ARM32: vcmp.f32
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: movpl [[R]], #1
define
internal
i32
@fcmpUgeDouble
(
double
%a
,
double
%b
)
{
define
internal
i32
@fcmpUgeDouble
(
double
%a
,
double
%b
)
{
entry:
entry:
...
@@ -399,6 +568,11 @@ entry:
...
@@ -399,6 +568,11 @@ entry:
; CHECK-LABEL: fcmpUgeDouble
; CHECK-LABEL: fcmpUgeDouble
; CHECK: ucomisd
; CHECK: ucomisd
; CHECK: setbe
; CHECK: setbe
; ARM32-LABEL: fcmpUgeDouble
; ARM32: vcmp.f64
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: movpl [[R]], #1
define
internal
i32
@fcmpUltFloat
(
float
%a
,
float
%b
)
{
define
internal
i32
@fcmpUltFloat
(
float
%a
,
float
%b
)
{
entry:
entry:
...
@@ -409,6 +583,11 @@ entry:
...
@@ -409,6 +583,11 @@ entry:
; CHECK-LABEL: fcmpUltFloat
; CHECK-LABEL: fcmpUltFloat
; CHECK: ucomiss
; CHECK: ucomiss
; CHECK: setb
; CHECK: setb
; ARM32-LABEL: fcmpUltFloat
; ARM32: vcmp.f32
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: movlt [[R]], #1
define
internal
i32
@fcmpUltDouble
(
double
%a
,
double
%b
)
{
define
internal
i32
@fcmpUltDouble
(
double
%a
,
double
%b
)
{
entry:
entry:
...
@@ -419,6 +598,11 @@ entry:
...
@@ -419,6 +598,11 @@ entry:
; CHECK-LABEL: fcmpUltDouble
; CHECK-LABEL: fcmpUltDouble
; CHECK: ucomisd
; CHECK: ucomisd
; CHECK: setb
; CHECK: setb
; ARM32-LABEL: fcmpUltDouble
; ARM32: vcmp.f64
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: movlt [[R]], #1
define
internal
i32
@fcmpUleFloat
(
float
%a
,
float
%b
)
{
define
internal
i32
@fcmpUleFloat
(
float
%a
,
float
%b
)
{
entry:
entry:
...
@@ -429,6 +613,11 @@ entry:
...
@@ -429,6 +613,11 @@ entry:
; CHECK-LABEL: fcmpUleFloat
; CHECK-LABEL: fcmpUleFloat
; CHECK: ucomiss
; CHECK: ucomiss
; CHECK: setbe
; CHECK: setbe
; ARM32-LABEL: fcmpUleFloat
; ARM32: vcmp.f32
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: movle [[R]], #1
define
internal
i32
@fcmpUleDouble
(
double
%a
,
double
%b
)
{
define
internal
i32
@fcmpUleDouble
(
double
%a
,
double
%b
)
{
entry:
entry:
...
@@ -439,6 +628,11 @@ entry:
...
@@ -439,6 +628,11 @@ entry:
; CHECK-LABEL: fcmpUleDouble
; CHECK-LABEL: fcmpUleDouble
; CHECK: ucomisd
; CHECK: ucomisd
; CHECK: setbe
; CHECK: setbe
; ARM32-LABEL: fcmpUleDouble
; ARM32: vcmp.f64
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: movle [[R]], #1
define
internal
i32
@fcmpUneFloat
(
float
%a
,
float
%b
)
{
define
internal
i32
@fcmpUneFloat
(
float
%a
,
float
%b
)
{
entry:
entry:
...
@@ -450,6 +644,11 @@ entry:
...
@@ -450,6 +644,11 @@ entry:
; CHECK: ucomiss
; CHECK: ucomiss
; CHECK: jne
; CHECK: jne
; CHECK: jp
; CHECK: jp
; ARM32-LABEL: fcmpUneFloat
; ARM32: vcmp.f32
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: movne [[R]], #1
define
internal
i32
@fcmpUneDouble
(
double
%a
,
double
%b
)
{
define
internal
i32
@fcmpUneDouble
(
double
%a
,
double
%b
)
{
entry:
entry:
...
@@ -461,6 +660,11 @@ entry:
...
@@ -461,6 +660,11 @@ entry:
; CHECK: ucomisd
; CHECK: ucomisd
; CHECK: jne
; CHECK: jne
; CHECK: jp
; CHECK: jp
; ARM32-LABEL: fcmpUneDouble
; ARM32: vcmp.f64
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: movne [[R]], #1
define
internal
i32
@fcmpUnoFloat
(
float
%a
,
float
%b
)
{
define
internal
i32
@fcmpUnoFloat
(
float
%a
,
float
%b
)
{
entry:
entry:
...
@@ -471,6 +675,11 @@ entry:
...
@@ -471,6 +675,11 @@ entry:
; CHECK-LABEL: fcmpUnoFloat
; CHECK-LABEL: fcmpUnoFloat
; CHECK: ucomiss
; CHECK: ucomiss
; CHECK: setp
; CHECK: setp
; ARM32-LABEL: fcmpUnoFloat
; ARM32: vcmp.f32
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: movvs [[R]], #1
define
internal
i32
@fcmpUnoDouble
(
double
%a
,
double
%b
)
{
define
internal
i32
@fcmpUnoDouble
(
double
%a
,
double
%b
)
{
entry:
entry:
...
@@ -481,6 +690,11 @@ entry:
...
@@ -481,6 +690,11 @@ entry:
; CHECK-LABEL: fcmpUnoDouble
; CHECK-LABEL: fcmpUnoDouble
; CHECK: ucomisd
; CHECK: ucomisd
; CHECK: setp
; CHECK: setp
; ARM32-LABEL: fcmpUnoDouble
; ARM32: vcmp.f64
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: movvs [[R]], #1
define
internal
i32
@fcmpTrueFloat
(
float
%a
,
float
%b
)
{
define
internal
i32
@fcmpTrueFloat
(
float
%a
,
float
%b
)
{
entry:
entry:
...
@@ -490,6 +704,9 @@ entry:
...
@@ -490,6 +704,9 @@ entry:
}
}
; CHECK-LABEL: fcmpTrueFloat
; CHECK-LABEL: fcmpTrueFloat
; CHECK: mov {{.*}},0x1
; CHECK: mov {{.*}},0x1
; ARM32-LABEL: fcmpTrueFloat
; ARM32: vcmp.f32
; ARM32: mov [[R]], #1
define
internal
i32
@fcmpTrueDouble
(
double
%a
,
double
%b
)
{
define
internal
i32
@fcmpTrueDouble
(
double
%a
,
double
%b
)
{
entry:
entry:
...
@@ -499,6 +716,9 @@ entry:
...
@@ -499,6 +716,9 @@ entry:
}
}
; CHECK-LABEL: fcmpTrueDouble
; CHECK-LABEL: fcmpTrueDouble
; CHECK: mov {{.*}},0x1
; CHECK: mov {{.*}},0x1
; ARM32-LABEL: fcmpTrueDouble
; ARM32: vcmp.f64
; ARM32: mov [[R]], #1
define
internal
float
@selectFloatVarVar
(
float
%a
,
float
%b
)
{
define
internal
float
@selectFloatVarVar
(
float
%a
,
float
%b
)
{
entry:
entry:
...
@@ -510,6 +730,10 @@ entry:
...
@@ -510,6 +730,10 @@ entry:
; CHECK: ucomiss
; CHECK: ucomiss
; CHECK: seta
; CHECK: seta
; CHECK: fld
; CHECK: fld
; ARM32-LABEL: selectFloatVarVar
; ARM32: vcmp.f32
; ARM32: vmovne.f32 s{{[0-9]+}}
; ARM32: bx
define
internal
double
@selectDoubleVarVar
(
double
%a
,
double
%b
)
{
define
internal
double
@selectDoubleVarVar
(
double
%a
,
double
%b
)
{
entry:
entry:
...
@@ -521,3 +745,7 @@ entry:
...
@@ -521,3 +745,7 @@ entry:
; CHECK: ucomisd
; CHECK: ucomisd
; CHECK: seta
; CHECK: seta
; CHECK: fld
; CHECK: fld
; ARM32-LABEL: selectDoubleVarVar
; ARM32: vcmp.f64
; ARM32: vmovne.f64 d{{[0-9]+}}
; ARM32: bx
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment