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
d1e97776
Commit
d1e97776
authored
Jul 07, 2016
by
Mohit Bhakkad
Committed by
Jim Stichnoth
Jul 07, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
SubZero: legalize for f32/f64 constants in MIPS32
R=stichnot@chromium.org Review URL:
https://codereview.chromium.org/2123723002
. Patch from Mohit Bhakkad <mohit.bhakkad@imgtec.com>.
parent
36847bdd
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
131 additions
and
60 deletions
+131
-60
IceInstMIPS32.cpp
src/IceInstMIPS32.cpp
+25
-3
IceInstMIPS32.h
src/IceInstMIPS32.h
+45
-19
IceTargetLoweringMIPS32.cpp
src/IceTargetLoweringMIPS32.cpp
+50
-31
IceTargetLoweringMIPS32.h
src/IceTargetLoweringMIPS32.h
+11
-7
No files found.
src/IceInstMIPS32.cpp
View file @
d1e97776
...
...
@@ -46,7 +46,7 @@ bool OperandMIPS32Mem::canHoldOffset(Type Ty, bool SignExt, int32_t Offset) {
}
OperandMIPS32Mem
::
OperandMIPS32Mem
(
Cfg
*
Func
,
Type
Ty
,
Variable
*
Base
,
ConstantInteger32
*
ImmOffset
,
AddrMode
Mode
)
Operand
*
ImmOffset
,
AddrMode
Mode
)
:
OperandMIPS32
(
kMem
,
Ty
),
Base
(
Base
),
ImmOffset
(
ImmOffset
),
Mode
(
Mode
)
{
// The Neg modes are only needed for Reg +/- Reg.
(
void
)
Func
;
...
...
@@ -121,6 +121,25 @@ template <> const char *InstMIPS32Trunc_w_s::Opcode = "trunc.w.s";
template
<>
const
char
*
InstMIPS32Xor
::
Opcode
=
"xor"
;
template
<>
const
char
*
InstMIPS32Xori
::
Opcode
=
"xori"
;
template
<>
void
InstMIPS32Lui
::
emit
(
const
Cfg
*
Func
)
const
{
if
(
!
BuildDefs
::
dump
())
return
;
Ostream
&
Str
=
Func
->
getContext
()
->
getStrEmit
();
assert
(
getSrcSize
()
==
1
);
Str
<<
"
\t
"
<<
Opcode
<<
"
\t
"
;
getDest
()
->
emit
(
Func
);
Str
<<
", "
;
auto
*
Src0
=
llvm
::
cast
<
Constant
>
(
getSrc
(
0
));
if
(
auto
*
CR
=
llvm
::
dyn_cast
<
ConstantRelocatable
>
(
Src0
))
{
emitRelocOp
(
Str
,
Reloc
);
Str
<<
"("
;
CR
->
emitWithoutPrefix
(
Func
->
getTarget
());
Str
<<
")"
;
}
else
{
Src0
->
emit
(
Func
);
}
}
template
<>
void
InstMIPS32Mflo
::
emit
(
const
Cfg
*
Func
)
const
{
if
(
!
BuildDefs
::
dump
())
return
;
...
...
@@ -260,8 +279,11 @@ void OperandMIPS32Mem::emit(const Cfg *Func) const {
if
(
!
BuildDefs
::
dump
())
return
;
Ostream
&
Str
=
Func
->
getContext
()
->
getStrEmit
();
ConstantInteger32
*
Offset
=
getOffset
();
Offset
->
emit
(
Func
);
Operand
*
Offset
=
getOffset
();
if
(
auto
*
CR
=
llvm
::
dyn_cast
<
ConstantRelocatable
>
(
Offset
))
{
CR
->
emitWithoutPrefix
(
Func
->
getTarget
());
}
else
Offset
->
emit
(
Func
);
Str
<<
"("
;
getBase
()
->
emit
(
Func
);
Str
<<
")"
;
...
...
src/IceInstMIPS32.h
View file @
d1e97776
...
...
@@ -28,6 +28,21 @@
namespace
Ice
{
namespace
MIPS32
{
enum
RelocOp
{
RO_No
,
RO_Hi
,
RO_Lo
};
inline
void
emitRelocOp
(
Ostream
&
Str
,
RelocOp
Reloc
)
{
switch
(
Reloc
)
{
case
RO_No
:
break
;
case
RO_Hi
:
Str
<<
"%hi"
;
break
;
case
RO_Lo
:
Str
<<
"%lo"
;
break
;
}
}
class
TargetMIPS32
;
/// OperandMips32 extends the Operand hierarchy.
...
...
@@ -72,14 +87,13 @@ public:
/// general Constant operands like ConstantRelocatable, since a relocatable
/// can potentially take up too many bits.
static
OperandMIPS32Mem
*
create
(
Cfg
*
Func
,
Type
Ty
,
Variable
*
Base
,
ConstantInteger32
*
ImmOffset
,
AddrMode
Mode
=
Offset
)
{
Operand
*
ImmOffset
,
AddrMode
Mode
=
Offset
)
{
return
new
(
Func
->
allocate
<
OperandMIPS32Mem
>
())
OperandMIPS32Mem
(
Func
,
Ty
,
Base
,
ImmOffset
,
Mode
);
}
Variable
*
getBase
()
const
{
return
Base
;
}
ConstantInteger32
*
getOffset
()
const
{
return
ImmOffset
;
}
Operand
*
getOffset
()
const
{
return
ImmOffset
;
}
AddrMode
getAddrMode
()
const
{
return
Mode
;
}
void
emit
(
const
Cfg
*
Func
)
const
override
;
...
...
@@ -101,12 +115,12 @@ public:
}
private
:
OperandMIPS32Mem
(
Cfg
*
Func
,
Type
Ty
,
Variable
*
Base
,
ConstantInteger32
*
ImmOffset
,
AddrMode
Mode
);
OperandMIPS32Mem
(
Cfg
*
Func
,
Type
Ty
,
Variable
*
Base
,
Operand
*
ImmOffset
,
AddrMode
Mode
);
Variable
*
Base
;
ConstantInteger32
*
ImmOffset
;
AddrMode
Mode
;
Operand
*
const
ImmOffset
;
const
AddrMode
Mode
;
};
/// Base class for Mips instructions.
...
...
@@ -254,9 +268,10 @@ class InstMIPS32UnaryopGPR : public InstMIPS32 {
InstMIPS32UnaryopGPR
&
operator
=
(
const
InstMIPS32UnaryopGPR
&
)
=
delete
;
public
:
static
InstMIPS32UnaryopGPR
*
create
(
Cfg
*
Func
,
Variable
*
Dest
,
Operand
*
Src
)
{
static
InstMIPS32UnaryopGPR
*
create
(
Cfg
*
Func
,
Variable
*
Dest
,
Operand
*
Src
,
RelocOp
Reloc
=
RO_No
)
{
return
new
(
Func
->
allocate
<
InstMIPS32UnaryopGPR
>
())
InstMIPS32UnaryopGPR
(
Func
,
Dest
,
Src
);
InstMIPS32UnaryopGPR
(
Func
,
Dest
,
Src
,
Reloc
);
}
void
emit
(
const
Cfg
*
Func
)
const
override
{
if
(
!
BuildDefs
::
dump
())
...
...
@@ -280,13 +295,15 @@ public:
static
bool
classof
(
const
Inst
*
Inst
)
{
return
isClassof
(
Inst
,
K
);
}
protected
:
InstMIPS32UnaryopGPR
(
Cfg
*
Func
,
Variable
*
Dest
,
Operand
*
Src
)
:
InstMIPS32
(
Func
,
K
,
1
,
Dest
)
{
InstMIPS32UnaryopGPR
(
Cfg
*
Func
,
Variable
*
Dest
,
Operand
*
Src
,
RelocOp
Reloc
=
RO_No
)
:
InstMIPS32
(
Func
,
K
,
1
,
Dest
),
Reloc
(
Reloc
)
{
addSource
(
Src
);
}
private
:
static
const
char
*
Opcode
;
const
RelocOp
Reloc
;
};
/// Instructions of the form opcode reg, reg.
...
...
@@ -485,9 +502,10 @@ class InstMIPS32Memory : public InstMIPS32 {
public
:
static
InstMIPS32Memory
*
create
(
Cfg
*
Func
,
Variable
*
Value
,
OperandMIPS32Mem
*
Mem
)
{
OperandMIPS32Mem
*
Mem
,
RelocOp
Reloc
=
RO_No
)
{
return
new
(
Func
->
allocate
<
InstMIPS32Memory
>
())
InstMIPS32Memory
(
Func
,
Value
,
Mem
);
InstMIPS32Memory
(
Func
,
Value
,
Mem
,
Reloc
);
}
void
emit
(
const
Cfg
*
Func
)
const
override
{
...
...
@@ -498,7 +516,10 @@ public:
Str
<<
"
\t
"
<<
Opcode
<<
"
\t
"
;
getSrc
(
0
)
->
emit
(
Func
);
Str
<<
", "
;
emitRelocOp
(
Str
,
Reloc
);
Str
<<
(
Reloc
?
"("
:
""
);
getSrc
(
1
)
->
emit
(
Func
);
Str
<<
(
Reloc
?
")"
:
""
);
}
void
emitIAS
(
const
Cfg
*
Func
)
const
override
{
...
...
@@ -511,20 +532,24 @@ public:
return
;
Ostream
&
Str
=
Func
->
getContext
()
->
getStrDump
();
Str
<<
"
\t
"
<<
Opcode
<<
"
\t
"
;
Str
<<
" "
;
getSrc
(
1
)
->
dump
(
Func
);
Str
<<
", "
;
getSrc
(
0
)
->
dump
(
Func
);
Str
<<
", "
;
emitRelocOp
(
Str
,
Reloc
);
Str
<<
(
Reloc
?
"("
:
""
);
getSrc
(
1
)
->
dump
(
Func
);
Str
<<
(
Reloc
?
")"
:
""
);
}
static
bool
classof
(
const
Inst
*
Inst
)
{
return
isClassof
(
Inst
,
K
);
}
private
:
InstMIPS32Memory
(
Cfg
*
Func
,
Variable
*
Value
,
OperandMIPS32Mem
*
Mem
)
:
InstMIPS32
(
Func
,
K
,
2
,
nullptr
)
{
InstMIPS32Memory
(
Cfg
*
Func
,
Variable
*
Value
,
OperandMIPS32Mem
*
Mem
,
RelocOp
Reloc
=
RO_No
)
:
InstMIPS32
(
Func
,
K
,
2
,
nullptr
),
Reloc
(
Reloc
)
{
addSource
(
Value
);
addSource
(
Mem
);
}
static
const
char
*
Opcode
;
const
RelocOp
Reloc
;
};
// InstMIPS32Label represents an intra-block label that is the target of an
...
...
@@ -735,7 +760,7 @@ using InstMIPS32Div_s = InstMIPS32ThreeAddrFPR<InstMIPS32::Div_s>;
using
InstMIPS32Divu
=
InstMIPS32ThreeAddrGPR
<
InstMIPS32
::
Divu
>
;
using
InstMIPS32La
=
InstMIPS32UnaryopGPR
<
InstMIPS32
::
La
>
;
using
InstMIPS32Ldc1
=
InstMIPS32Memory
<
InstMIPS32
::
Ldc1
>
;
using
InstMIPS32Lui
=
InstMIPS32
Imm16
<
InstMIPS32
::
Lui
>
;
using
InstMIPS32Lui
=
InstMIPS32
UnaryopGPR
<
InstMIPS32
::
Lui
>
;
using
InstMIPS32Lw
=
InstMIPS32Memory
<
InstMIPS32
::
Lw
>
;
using
InstMIPS32Lwc1
=
InstMIPS32Memory
<
InstMIPS32
::
Lwc1
>
;
using
InstMIPS32Mfc1
=
InstMIPS32TwoAddrGPR
<
InstMIPS32
::
Mfc1
>
;
...
...
@@ -827,6 +852,7 @@ template <> void InstMIPS32Mtlo::emit(const Cfg *Func) const;
template
<>
void
InstMIPS32Mthi
::
emit
(
const
Cfg
*
Func
)
const
;
template
<>
void
InstMIPS32Mult
::
emit
(
const
Cfg
*
Func
)
const
;
template
<>
void
InstMIPS32Multu
::
emit
(
const
Cfg
*
Func
)
const
;
template
<>
void
InstMIPS32Lui
::
emit
(
const
Cfg
*
Func
)
const
;
}
// end of namespace MIPS32
}
// end of namespace Ice
...
...
src/IceTargetLoweringMIPS32.cpp
View file @
d1e97776
...
...
@@ -1021,7 +1021,7 @@ Operand *TargetMIPS32::hiOperand(Operand *Operand) {
assert
(
Mem
->
getAddrMode
()
==
OperandMIPS32Mem
::
Offset
);
const
Type
SplitType
=
IceType_i32
;
Variable
*
Base
=
Mem
->
getBase
();
ConstantInteger32
*
Offset
=
Mem
->
getOffset
(
);
auto
*
Offset
=
llvm
::
cast
<
ConstantInteger32
>
(
Mem
->
getOffset
()
);
assert
(
!
Utils
::
WouldOverflowAdd
(
Offset
->
getValue
(),
4
));
int32_t
NextOffsetVal
=
Offset
->
getValue
()
+
4
;
constexpr
bool
SignExt
=
false
;
...
...
@@ -2214,38 +2214,57 @@ Operand *TargetMIPS32::legalize(Operand *From, LegalMask Allowed,
// Given the above assertion, if type of operand is not legal
// (e.g., OperandMIPS32Mem and !Legal_Mem), we can always copy
// to a register.
if
(
auto
*
C
=
llvm
::
dyn_cast
<
ConstantRelocatable
>
(
From
))
{
(
void
)
C
;
// TODO(reed kotler): complete this case for proper implementation
Variable
*
Reg
=
makeReg
(
Ty
,
RegNum
);
Context
.
insert
<
InstFakeDef
>
(
Reg
);
return
Reg
;
}
else
if
(
auto
*
C32
=
llvm
::
dyn_cast
<
ConstantInteger32
>
(
From
))
{
const
uint32_t
Value
=
C32
->
getValue
();
// Check if the immediate will fit in a Flexible second operand,
// if a Flexible second operand is allowed. We need to know the exact
// value, so that rules out relocatable constants.
// Also try the inverse and use MVN if possible.
// Do a movw/movt to a register.
Variable
*
Reg
;
if
(
RegNum
.
hasValue
())
Reg
=
getPhysicalRegister
(
RegNum
);
else
Reg
=
makeReg
(
Ty
,
RegNum
);
if
(
isInt
<
16
>
(
int32_t
(
Value
)))
{
Variable
*
Zero
=
getPhysicalRegister
(
RegMIPS32
::
Reg_ZERO
,
Ty
);
Context
.
insert
<
InstFakeDef
>
(
Zero
);
_addiu
(
Reg
,
Zero
,
Value
);
}
else
{
uint32_t
UpperBits
=
(
Value
>>
16
)
&
0xFFFF
;
(
void
)
UpperBits
;
uint32_t
LowerBits
=
Value
&
0xFFFF
;
Variable
*
TReg
=
makeReg
(
Ty
,
RegNum
);
_lui
(
TReg
,
UpperBits
);
_ori
(
Reg
,
TReg
,
LowerBits
);
if
(
llvm
::
isa
<
Constant
>
(
From
))
{
if
(
auto
*
C
=
llvm
::
dyn_cast
<
ConstantRelocatable
>
(
From
))
{
(
void
)
C
;
// TODO(reed kotler): complete this case for proper implementation
Variable
*
Reg
=
makeReg
(
Ty
,
RegNum
);
Context
.
insert
<
InstFakeDef
>
(
Reg
);
return
Reg
;
}
else
if
(
auto
*
C32
=
llvm
::
dyn_cast
<
ConstantInteger32
>
(
From
))
{
const
uint32_t
Value
=
C32
->
getValue
();
// Check if the immediate will fit in a Flexible second operand,
// if a Flexible second operand is allowed. We need to know the exact
// value, so that rules out relocatable constants.
// Also try the inverse and use MVN if possible.
// Do a movw/movt to a register.
Variable
*
Reg
;
if
(
RegNum
.
hasValue
())
Reg
=
getPhysicalRegister
(
RegNum
);
else
Reg
=
makeReg
(
Ty
,
RegNum
);
if
(
isInt
<
16
>
(
int32_t
(
Value
)))
{
Variable
*
Zero
=
getPhysicalRegister
(
RegMIPS32
::
Reg_ZERO
,
Ty
);
Context
.
insert
<
InstFakeDef
>
(
Zero
);
_addiu
(
Reg
,
Zero
,
Value
);
}
else
{
uint32_t
UpperBits
=
(
Value
>>
16
)
&
0xFFFF
;
(
void
)
UpperBits
;
uint32_t
LowerBits
=
Value
&
0xFFFF
;
Variable
*
TReg
=
makeReg
(
Ty
,
RegNum
);
_lui
(
TReg
,
Ctx
->
getConstantInt32
(
UpperBits
));
_ori
(
Reg
,
TReg
,
LowerBits
);
}
return
Reg
;
}
else
if
(
isScalarFloatingType
(
Ty
))
{
// Load floats/doubles from literal pool.
auto
*
CFrom
=
llvm
::
cast
<
Constant
>
(
From
);
assert
(
CFrom
->
getShouldBePooled
());
Constant
*
Offset
=
Ctx
->
getConstantSym
(
0
,
CFrom
->
getLabelName
());
Variable
*
TReg1
=
makeReg
(
getPointerType
());
Variable
*
TReg2
=
makeReg
(
Ty
);
Context
.
insert
<
InstFakeDef
>
(
TReg2
);
_lui
(
TReg1
,
Offset
,
RO_Hi
);
OperandMIPS32Mem
*
Addr
=
OperandMIPS32Mem
::
create
(
Func
,
Ty
,
TReg1
,
Offset
);
if
(
Ty
==
IceType_f32
)
_lwc1
(
TReg2
,
Addr
,
RO_Lo
);
else
_ldc1
(
TReg2
,
Addr
,
RO_Lo
);
return
copyToReg
(
TReg2
,
RegNum
);
}
return
Reg
;
}
if
(
auto
*
Var
=
llvm
::
dyn_cast
<
Variable
>
(
From
))
{
// Check if the variable is guaranteed a physical register. This
// can happen either when the variable is pre-colored or when it is
...
...
src/IceTargetLoweringMIPS32.h
View file @
d1e97776
...
...
@@ -35,7 +35,11 @@ public:
static
void
staticInit
(
GlobalContext
*
Ctx
);
static
bool
shouldBePooled
(
const
Constant
*
C
)
{
(
void
)
C
;
if
(
auto
*
ConstDouble
=
llvm
::
dyn_cast
<
ConstantDouble
>
(
C
))
{
return
!
Utils
::
isPositiveZero
(
ConstDouble
->
getValue
());
}
if
(
llvm
::
isa
<
ConstantFloat
>
(
C
))
return
true
;
return
false
;
}
static
std
::
unique_ptr
<::
Ice
::
TargetLowering
>
create
(
Cfg
*
Func
)
{
...
...
@@ -230,20 +234,20 @@ public:
Context
.
insert
<
InstMIPS32Divu
>
(
Dest
,
Src0
,
Src1
);
}
void
_ldc1
(
Variable
*
Value
,
OperandMIPS32Mem
*
Mem
)
{
Context
.
insert
<
InstMIPS32Ldc1
>
(
Value
,
Mem
);
void
_ldc1
(
Variable
*
Value
,
OperandMIPS32Mem
*
Mem
,
RelocOp
Reloc
=
RO_No
)
{
Context
.
insert
<
InstMIPS32Ldc1
>
(
Value
,
Mem
,
Reloc
);
}
void
_lw
(
Variable
*
Value
,
OperandMIPS32Mem
*
Mem
)
{
Context
.
insert
<
InstMIPS32Lw
>
(
Value
,
Mem
);
}
void
_lwc1
(
Variable
*
Value
,
OperandMIPS32Mem
*
Mem
)
{
Context
.
insert
<
InstMIPS32Lwc1
>
(
Value
,
Mem
);
void
_lwc1
(
Variable
*
Value
,
OperandMIPS32Mem
*
Mem
,
RelocOp
Reloc
=
RO_No
)
{
Context
.
insert
<
InstMIPS32Lwc1
>
(
Value
,
Mem
,
Reloc
);
}
void
_lui
(
Variable
*
Dest
,
uint32_t
Imm
)
{
Context
.
insert
<
InstMIPS32Lui
>
(
Dest
,
Imm
);
void
_lui
(
Variable
*
Dest
,
Operand
*
Src
,
RelocOp
Reloc
=
RO_No
)
{
Context
.
insert
<
InstMIPS32Lui
>
(
Dest
,
Src
,
Reloc
);
}
void
_mov
(
Variable
*
Dest
,
Operand
*
Src0
)
{
...
...
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