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
6b80cf10
Commit
6b80cf10
authored
Jan 21, 2016
by
David Sehr
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Merge x86 data and header lowering
BUG= R=stichnot@chromium.org Review URL:
https://codereview.chromium.org/1616673004
.
parent
2c3c82e2
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
313 additions
and
535 deletions
+313
-535
Makefile.standalone
Makefile.standalone
+1
-0
IceTargetLoweringX86.cpp
src/IceTargetLoweringX86.cpp
+50
-0
IceTargetLoweringX8632.cpp
src/IceTargetLoweringX8632.cpp
+3
-224
IceTargetLoweringX8632.h
src/IceTargetLoweringX8632.h
+2
-46
IceTargetLoweringX8664.cpp
src/IceTargetLoweringX8664.cpp
+3
-214
IceTargetLoweringX8664.h
src/IceTargetLoweringX8664.h
+3
-51
IceTargetLoweringX86Base.h
src/IceTargetLoweringX86Base.h
+49
-0
IceTargetLoweringX86BaseImpl.h
src/IceTargetLoweringX86BaseImpl.h
+202
-0
No files found.
Makefile.standalone
View file @
6b80cf10
...
...
@@ -250,6 +250,7 @@ SRCS = \
IceTargetLowering.cpp
\
IceTargetLoweringARM32.cpp
\
IceTargetLoweringMIPS32.cpp
\
IceTargetLoweringX86.cpp
\
IceTargetLoweringX8632.cpp
\
IceTargetLoweringX8664.cpp
\
IceAssembler.cpp
\
...
...
src/IceTargetLoweringX86.cpp
0 → 100644
View file @
6b80cf10
//===---- subzero/src/IceTargetLoweringX86.cpp - x86 lowering -*- C++ -*---===//
//
// The Subzero Code Generator
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief Implements portions of the TargetLoweringX86Base class, and related
/// classes.
///
//===----------------------------------------------------------------------===//
// Choose one namespace, since including this file should not cause the
// templates to be instantiated. This avoids duplicating the PoolTypeConverter
// data items, but is ugly as code common to all of x86 is including code
// specific to one of 32 or 64.
// TODO(jpp): replace this ugliness with the beauty of extern template.
#define X86NAMESPACE X8632
#include "IceTargetLoweringX86Base.h"
#undef X86NAMESPACE
namespace
Ice
{
namespace
X86
{
const
char
*
PoolTypeConverter
<
float
>::
TypeName
=
"float"
;
const
char
*
PoolTypeConverter
<
float
>::
AsmTag
=
".long"
;
const
char
*
PoolTypeConverter
<
float
>::
PrintfString
=
"0x%x"
;
const
char
*
PoolTypeConverter
<
double
>::
TypeName
=
"double"
;
const
char
*
PoolTypeConverter
<
double
>::
AsmTag
=
".quad"
;
const
char
*
PoolTypeConverter
<
double
>::
PrintfString
=
"0x%llx"
;
const
char
*
PoolTypeConverter
<
uint32_t
>::
TypeName
=
"i32"
;
const
char
*
PoolTypeConverter
<
uint32_t
>::
AsmTag
=
".long"
;
const
char
*
PoolTypeConverter
<
uint32_t
>::
PrintfString
=
"0x%x"
;
const
char
*
PoolTypeConverter
<
uint16_t
>::
TypeName
=
"i16"
;
const
char
*
PoolTypeConverter
<
uint16_t
>::
AsmTag
=
".short"
;
const
char
*
PoolTypeConverter
<
uint16_t
>::
PrintfString
=
"0x%x"
;
const
char
*
PoolTypeConverter
<
uint8_t
>::
TypeName
=
"i8"
;
const
char
*
PoolTypeConverter
<
uint8_t
>::
AsmTag
=
".byte"
;
const
char
*
PoolTypeConverter
<
uint8_t
>::
PrintfString
=
"0x%x"
;
}
// end of namespace X86
}
// end of namespace Ice
src/IceTargetLoweringX8632.cpp
View file @
6b80cf10
...
...
@@ -24,12 +24,13 @@ std::unique_ptr<::Ice::TargetLowering> createTargetLowering(::Ice::Cfg *Func) {
std
::
unique_ptr
<::
Ice
::
TargetDataLowering
>
createTargetDataLowering
(
::
Ice
::
GlobalContext
*
Ctx
)
{
return
::
Ice
::
X8632
::
TargetDataX8632
::
create
(
Ctx
);
return
::
Ice
::
X8632
::
TargetDataX86
<::
Ice
::
X8632
::
TargetX8632Traits
>::
create
(
Ctx
);
}
std
::
unique_ptr
<::
Ice
::
TargetHeaderLowering
>
createTargetHeaderLowering
(
::
Ice
::
GlobalContext
*
Ctx
)
{
return
::
Ice
::
X8632
::
TargetHeaderX86
32
::
create
(
Ctx
);
return
::
Ice
::
X8632
::
TargetHeaderX86
::
create
(
Ctx
);
}
void
staticInit
(
::
Ice
::
GlobalContext
*
Ctx
)
{
...
...
@@ -269,228 +270,6 @@ void TargetX8632::emitSandboxedReturn() {
lowerIndirectJump
(
T_ecx
);
}
void
TargetX8632
::
emitJumpTable
(
const
Cfg
*
Func
,
const
InstJumpTable
*
JumpTable
)
const
{
if
(
!
BuildDefs
::
dump
())
return
;
Ostream
&
Str
=
Ctx
->
getStrEmit
();
const
bool
UseNonsfi
=
Ctx
->
getFlags
().
getUseNonsfi
();
const
IceString
MangledName
=
Ctx
->
mangleName
(
Func
->
getFunctionName
());
const
IceString
Prefix
=
UseNonsfi
?
".data.rel.ro."
:
".rodata."
;
Str
<<
"
\t
.section
\t
"
<<
Prefix
<<
MangledName
<<
"$jumptable,
\"
a
\"
,@progbits
\n
"
;
Str
<<
"
\t
.align
\t
"
<<
typeWidthInBytes
(
getPointerType
())
<<
"
\n
"
;
Str
<<
InstJumpTable
::
makeName
(
MangledName
,
JumpTable
->
getId
())
<<
":"
;
// On X8632 pointers are 32-bit hence the use of .long
for
(
SizeT
I
=
0
;
I
<
JumpTable
->
getNumTargets
();
++
I
)
Str
<<
"
\n\t
.long
\t
"
<<
JumpTable
->
getTarget
(
I
)
->
getAsmName
();
Str
<<
"
\n
"
;
}
TargetDataX8632
::
TargetDataX8632
(
GlobalContext
*
Ctx
)
:
TargetDataLowering
(
Ctx
)
{}
namespace
{
template
<
typename
T
>
struct
PoolTypeConverter
{};
template
<>
struct
PoolTypeConverter
<
float
>
{
using
PrimitiveIntType
=
uint32_t
;
using
IceType
=
ConstantFloat
;
static
const
Type
Ty
=
IceType_f32
;
static
const
char
*
TypeName
;
static
const
char
*
AsmTag
;
static
const
char
*
PrintfString
;
};
const
char
*
PoolTypeConverter
<
float
>::
TypeName
=
"float"
;
const
char
*
PoolTypeConverter
<
float
>::
AsmTag
=
".long"
;
const
char
*
PoolTypeConverter
<
float
>::
PrintfString
=
"0x%x"
;
template
<>
struct
PoolTypeConverter
<
double
>
{
using
PrimitiveIntType
=
uint64_t
;
using
IceType
=
ConstantDouble
;
static
const
Type
Ty
=
IceType_f64
;
static
const
char
*
TypeName
;
static
const
char
*
AsmTag
;
static
const
char
*
PrintfString
;
};
const
char
*
PoolTypeConverter
<
double
>::
TypeName
=
"double"
;
const
char
*
PoolTypeConverter
<
double
>::
AsmTag
=
".quad"
;
const
char
*
PoolTypeConverter
<
double
>::
PrintfString
=
"0x%llx"
;
// Add converter for int type constant pooling
template
<>
struct
PoolTypeConverter
<
uint32_t
>
{
using
PrimitiveIntType
=
uint32_t
;
using
IceType
=
ConstantInteger32
;
static
const
Type
Ty
=
IceType_i32
;
static
const
char
*
TypeName
;
static
const
char
*
AsmTag
;
static
const
char
*
PrintfString
;
};
const
char
*
PoolTypeConverter
<
uint32_t
>::
TypeName
=
"i32"
;
const
char
*
PoolTypeConverter
<
uint32_t
>::
AsmTag
=
".long"
;
const
char
*
PoolTypeConverter
<
uint32_t
>::
PrintfString
=
"0x%x"
;
// Add converter for int type constant pooling
template
<>
struct
PoolTypeConverter
<
uint16_t
>
{
using
PrimitiveIntType
=
uint32_t
;
using
IceType
=
ConstantInteger32
;
static
const
Type
Ty
=
IceType_i16
;
static
const
char
*
TypeName
;
static
const
char
*
AsmTag
;
static
const
char
*
PrintfString
;
};
const
char
*
PoolTypeConverter
<
uint16_t
>::
TypeName
=
"i16"
;
const
char
*
PoolTypeConverter
<
uint16_t
>::
AsmTag
=
".short"
;
const
char
*
PoolTypeConverter
<
uint16_t
>::
PrintfString
=
"0x%x"
;
// Add converter for int type constant pooling
template
<>
struct
PoolTypeConverter
<
uint8_t
>
{
using
PrimitiveIntType
=
uint32_t
;
using
IceType
=
ConstantInteger32
;
static
const
Type
Ty
=
IceType_i8
;
static
const
char
*
TypeName
;
static
const
char
*
AsmTag
;
static
const
char
*
PrintfString
;
};
const
char
*
PoolTypeConverter
<
uint8_t
>::
TypeName
=
"i8"
;
const
char
*
PoolTypeConverter
<
uint8_t
>::
AsmTag
=
".byte"
;
const
char
*
PoolTypeConverter
<
uint8_t
>::
PrintfString
=
"0x%x"
;
}
// end of anonymous namespace
template
<
typename
T
>
void
TargetDataX8632
::
emitConstantPool
(
GlobalContext
*
Ctx
)
{
if
(
!
BuildDefs
::
dump
())
return
;
Ostream
&
Str
=
Ctx
->
getStrEmit
();
Type
Ty
=
T
::
Ty
;
SizeT
Align
=
typeAlignInBytes
(
Ty
);
ConstantList
Pool
=
Ctx
->
getConstantPool
(
Ty
);
Str
<<
"
\t
.section
\t
.rodata.cst"
<<
Align
<<
",
\"
aM
\"
,@progbits,"
<<
Align
<<
"
\n
"
;
Str
<<
"
\t
.align
\t
"
<<
Align
<<
"
\n
"
;
// If reorder-pooled-constants option is set to true, we need to shuffle the
// constant pool before emitting it.
if
(
Ctx
->
getFlags
().
shouldReorderPooledConstants
()
&&
!
Pool
.
empty
())
{
// Use the constant's kind value as the salt for creating random number
// generator.
Operand
::
OperandKind
K
=
(
*
Pool
.
begin
())
->
getKind
();
RandomNumberGenerator
RNG
(
Ctx
->
getFlags
().
getRandomSeed
(),
RPE_PooledConstantReordering
,
K
);
RandomShuffle
(
Pool
.
begin
(),
Pool
.
end
(),
[
&
RNG
](
uint64_t
N
)
{
return
(
uint32_t
)
RNG
.
next
(
N
);
});
}
for
(
Constant
*
C
:
Pool
)
{
if
(
!
C
->
getShouldBePooled
())
continue
;
auto
*
Const
=
llvm
::
cast
<
typename
T
::
IceType
>
(
C
);
typename
T
::
IceType
::
PrimType
Value
=
Const
->
getValue
();
// Use memcpy() to copy bits from Value into RawValue in a way that avoids
// breaking strict-aliasing rules.
typename
T
::
PrimitiveIntType
RawValue
;
memcpy
(
&
RawValue
,
&
Value
,
sizeof
(
Value
));
char
buf
[
30
];
int
CharsPrinted
=
snprintf
(
buf
,
llvm
::
array_lengthof
(
buf
),
T
::
PrintfString
,
RawValue
);
assert
(
CharsPrinted
>=
0
&&
(
size_t
)
CharsPrinted
<
llvm
::
array_lengthof
(
buf
));
(
void
)
CharsPrinted
;
// avoid warnings if asserts are disabled
Const
->
emitPoolLabel
(
Str
,
Ctx
);
Str
<<
":
\n\t
"
<<
T
::
AsmTag
<<
"
\t
"
<<
buf
<<
"
\t
/* "
<<
T
::
TypeName
<<
" "
<<
Value
<<
" */
\n
"
;
}
}
void
TargetDataX8632
::
lowerConstants
()
{
if
(
Ctx
->
getFlags
().
getDisableTranslation
())
return
;
// No need to emit constants from the int pool since (for x86) they are
// embedded as immediates in the instructions, just emit float/double.
switch
(
Ctx
->
getFlags
().
getOutFileType
())
{
case
FT_Elf
:
{
ELFObjectWriter
*
Writer
=
Ctx
->
getObjectWriter
();
Writer
->
writeConstantPool
<
ConstantInteger32
>
(
IceType_i8
);
Writer
->
writeConstantPool
<
ConstantInteger32
>
(
IceType_i16
);
Writer
->
writeConstantPool
<
ConstantInteger32
>
(
IceType_i32
);
Writer
->
writeConstantPool
<
ConstantFloat
>
(
IceType_f32
);
Writer
->
writeConstantPool
<
ConstantDouble
>
(
IceType_f64
);
}
break
;
case
FT_Asm
:
case
FT_Iasm
:
{
OstreamLocker
L
(
Ctx
);
emitConstantPool
<
PoolTypeConverter
<
uint8_t
>>
(
Ctx
);
emitConstantPool
<
PoolTypeConverter
<
uint16_t
>>
(
Ctx
);
emitConstantPool
<
PoolTypeConverter
<
uint32_t
>>
(
Ctx
);
emitConstantPool
<
PoolTypeConverter
<
float
>>
(
Ctx
);
emitConstantPool
<
PoolTypeConverter
<
double
>>
(
Ctx
);
}
break
;
}
}
void
TargetDataX8632
::
lowerJumpTables
()
{
const
bool
IsPIC
=
Ctx
->
getFlags
().
getUseNonsfi
();
switch
(
Ctx
->
getFlags
().
getOutFileType
())
{
case
FT_Elf
:
{
ELFObjectWriter
*
Writer
=
Ctx
->
getObjectWriter
();
for
(
const
JumpTableData
&
JT
:
Ctx
->
getJumpTables
())
Writer
->
writeJumpTable
(
JT
,
TargetX8632
::
Traits
::
FK_Abs
,
IsPIC
);
}
break
;
case
FT_Asm
:
// Already emitted from Cfg
break
;
case
FT_Iasm
:
{
if
(
!
BuildDefs
::
dump
())
return
;
Ostream
&
Str
=
Ctx
->
getStrEmit
();
const
IceString
Prefix
=
IsPIC
?
".data.rel.ro."
:
".rodata."
;
for
(
const
JumpTableData
&
JT
:
Ctx
->
getJumpTables
())
{
Str
<<
"
\t
.section
\t
"
<<
Prefix
<<
JT
.
getFunctionName
()
<<
"$jumptable,
\"
a
\"
,@progbits
\n
"
;
Str
<<
"
\t
.align
\t
"
<<
typeWidthInBytes
(
getPointerType
())
<<
"
\n
"
;
Str
<<
InstJumpTable
::
makeName
(
JT
.
getFunctionName
(),
JT
.
getId
())
<<
":"
;
// On X8632 pointers are 32-bit hence the use of .long
for
(
intptr_t
TargetOffset
:
JT
.
getTargetOffsets
())
Str
<<
"
\n\t
.long
\t
"
<<
JT
.
getFunctionName
()
<<
"+"
<<
TargetOffset
;
Str
<<
"
\n
"
;
}
}
break
;
}
}
void
TargetDataX8632
::
lowerGlobals
(
const
VariableDeclarationList
&
Vars
,
const
IceString
&
SectionSuffix
)
{
const
bool
IsPIC
=
Ctx
->
getFlags
().
getUseNonsfi
();
switch
(
Ctx
->
getFlags
().
getOutFileType
())
{
case
FT_Elf
:
{
ELFObjectWriter
*
Writer
=
Ctx
->
getObjectWriter
();
Writer
->
writeDataSection
(
Vars
,
TargetX8632
::
Traits
::
FK_Abs
,
SectionSuffix
,
IsPIC
);
}
break
;
case
FT_Asm
:
case
FT_Iasm
:
{
const
IceString
&
TranslateOnly
=
Ctx
->
getFlags
().
getTranslateOnly
();
OstreamLocker
L
(
Ctx
);
for
(
const
VariableDeclaration
*
Var
:
Vars
)
{
if
(
GlobalContext
::
matchSymbolName
(
Var
->
getName
(),
TranslateOnly
))
{
emitGlobal
(
*
Var
,
SectionSuffix
);
}
}
}
break
;
}
}
TargetHeaderX8632
::
TargetHeaderX8632
(
GlobalContext
*
Ctx
)
:
TargetHeaderLowering
(
Ctx
)
{}
// In some cases, there are x-macros tables for both high-level and low-level
// instructions/operands that use the same enum key value. The tables are kept
// separate to maintain a proper separation between abstraction layers. There
...
...
src/IceTargetLoweringX8632.h
View file @
6b80cf10
...
...
@@ -34,9 +34,6 @@ class TargetX8632 final : public ::Ice::X8632::TargetX86Base<X8632::Traits> {
TargetX8632
(
const
TargetX8632
&
)
=
delete
;
TargetX8632
&
operator
=
(
const
TargetX8632
&
)
=
delete
;
void
emitJumpTable
(
const
Cfg
*
Func
,
const
InstJumpTable
*
JumpTable
)
const
override
;
public
:
~
TargetX8632
()
=
default
;
...
...
@@ -70,55 +67,14 @@ private:
ENABLE_MAKE_UNIQUE
;
friend
class
X8632
::
TargetX86Base
<
X8632
::
Traits
>
;
explicit
TargetX8632
(
Cfg
*
Func
)
:
TargetX86Base
(
Func
)
{}
Operand
*
createNaClReadTPSrcOperand
()
{
Constant
*
Zero
=
Ctx
->
getConstantZero
(
IceType_i32
);
return
Traits
::
X86OperandMem
::
create
(
Func
,
IceType_i32
,
nullptr
,
Zero
,
nullptr
,
0
,
Traits
::
X86OperandMem
::
SegReg_GS
);
}
explicit
TargetX8632
(
Cfg
*
Func
)
:
TargetX86Base
(
Func
)
{}
};
class
TargetDataX8632
final
:
public
TargetDataLowering
{
TargetDataX8632
()
=
delete
;
TargetDataX8632
(
const
TargetDataX8632
&
)
=
delete
;
TargetDataX8632
&
operator
=
(
const
TargetDataX8632
&
)
=
delete
;
public
:
~
TargetDataX8632
()
override
=
default
;
static
std
::
unique_ptr
<
TargetDataLowering
>
create
(
GlobalContext
*
Ctx
)
{
return
makeUnique
<
TargetDataX8632
>
(
Ctx
);
}
void
lowerGlobals
(
const
VariableDeclarationList
&
Vars
,
const
IceString
&
SectionSuffix
)
override
;
void
lowerConstants
()
override
;
void
lowerJumpTables
()
override
;
private
:
ENABLE_MAKE_UNIQUE
;
explicit
TargetDataX8632
(
GlobalContext
*
Ctx
);
template
<
typename
T
>
static
void
emitConstantPool
(
GlobalContext
*
Ctx
);
};
class
TargetHeaderX8632
final
:
public
TargetHeaderLowering
{
TargetHeaderX8632
()
=
delete
;
TargetHeaderX8632
(
const
TargetHeaderX8632
&
)
=
delete
;
TargetHeaderX8632
&
operator
=
(
const
TargetHeaderX8632
&
)
=
delete
;
public
:
static
std
::
unique_ptr
<
TargetHeaderLowering
>
create
(
GlobalContext
*
Ctx
)
{
return
std
::
unique_ptr
<
TargetHeaderLowering
>
(
new
TargetHeaderX8632
(
Ctx
));
}
protected
:
explicit
TargetHeaderX8632
(
GlobalContext
*
Ctx
);
private
:
~
TargetHeaderX8632
()
=
default
;
};
}
// end of namespace X8632
...
...
src/IceTargetLoweringX8664.cpp
View file @
6b80cf10
...
...
@@ -24,12 +24,13 @@ std::unique_ptr<::Ice::TargetLowering> createTargetLowering(::Ice::Cfg *Func) {
std
::
unique_ptr
<::
Ice
::
TargetDataLowering
>
createTargetDataLowering
(
::
Ice
::
GlobalContext
*
Ctx
)
{
return
::
Ice
::
X8664
::
TargetDataX8664
::
create
(
Ctx
);
return
::
Ice
::
X8664
::
TargetDataX86
<::
Ice
::
X8664
::
TargetX8664Traits
>::
create
(
Ctx
);
}
std
::
unique_ptr
<::
Ice
::
TargetHeaderLowering
>
createTargetHeaderLowering
(
::
Ice
::
GlobalContext
*
Ctx
)
{
return
::
Ice
::
X8664
::
TargetHeaderX86
64
::
create
(
Ctx
);
return
::
Ice
::
X8664
::
TargetHeaderX86
::
create
(
Ctx
);
}
void
staticInit
(
::
Ice
::
GlobalContext
*
Ctx
)
{
...
...
@@ -547,218 +548,6 @@ void TargetX8664::emitSandboxedReturn() {
}
}
void
TargetX8664
::
emitJumpTable
(
const
Cfg
*
Func
,
const
InstJumpTable
*
JumpTable
)
const
{
if
(
!
BuildDefs
::
dump
())
return
;
Ostream
&
Str
=
Ctx
->
getStrEmit
();
IceString
MangledName
=
Ctx
->
mangleName
(
Func
->
getFunctionName
());
Str
<<
"
\t
.section
\t
.rodata."
<<
MangledName
<<
"$jumptable,
\"
a
\"
,@progbits
\n
"
;
Str
<<
"
\t
.align
\t
"
<<
typeWidthInBytes
(
getPointerType
())
<<
"
\n
"
;
Str
<<
InstJumpTable
::
makeName
(
MangledName
,
JumpTable
->
getId
())
<<
":"
;
// On X8664 ILP32 pointers are 32-bit hence the use of .long
for
(
SizeT
I
=
0
;
I
<
JumpTable
->
getNumTargets
();
++
I
)
Str
<<
"
\n\t
.long
\t
"
<<
JumpTable
->
getTarget
(
I
)
->
getAsmName
();
Str
<<
"
\n
"
;
}
namespace
{
template
<
typename
T
>
struct
PoolTypeConverter
{};
template
<>
struct
PoolTypeConverter
<
float
>
{
using
PrimitiveIntType
=
uint32_t
;
using
IceType
=
ConstantFloat
;
static
const
Type
Ty
=
IceType_f32
;
static
const
char
*
TypeName
;
static
const
char
*
AsmTag
;
static
const
char
*
PrintfString
;
};
const
char
*
PoolTypeConverter
<
float
>::
TypeName
=
"float"
;
const
char
*
PoolTypeConverter
<
float
>::
AsmTag
=
".long"
;
const
char
*
PoolTypeConverter
<
float
>::
PrintfString
=
"0x%x"
;
template
<>
struct
PoolTypeConverter
<
double
>
{
using
PrimitiveIntType
=
uint64_t
;
using
IceType
=
ConstantDouble
;
static
const
Type
Ty
=
IceType_f64
;
static
const
char
*
TypeName
;
static
const
char
*
AsmTag
;
static
const
char
*
PrintfString
;
};
const
char
*
PoolTypeConverter
<
double
>::
TypeName
=
"double"
;
const
char
*
PoolTypeConverter
<
double
>::
AsmTag
=
".quad"
;
const
char
*
PoolTypeConverter
<
double
>::
PrintfString
=
"0x%llx"
;
// Add converter for int type constant pooling
template
<>
struct
PoolTypeConverter
<
uint32_t
>
{
using
PrimitiveIntType
=
uint32_t
;
using
IceType
=
ConstantInteger32
;
static
const
Type
Ty
=
IceType_i32
;
static
const
char
*
TypeName
;
static
const
char
*
AsmTag
;
static
const
char
*
PrintfString
;
};
const
char
*
PoolTypeConverter
<
uint32_t
>::
TypeName
=
"i32"
;
const
char
*
PoolTypeConverter
<
uint32_t
>::
AsmTag
=
".long"
;
const
char
*
PoolTypeConverter
<
uint32_t
>::
PrintfString
=
"0x%x"
;
// Add converter for int type constant pooling
template
<>
struct
PoolTypeConverter
<
uint16_t
>
{
using
PrimitiveIntType
=
uint32_t
;
using
IceType
=
ConstantInteger32
;
static
const
Type
Ty
=
IceType_i16
;
static
const
char
*
TypeName
;
static
const
char
*
AsmTag
;
static
const
char
*
PrintfString
;
};
const
char
*
PoolTypeConverter
<
uint16_t
>::
TypeName
=
"i16"
;
const
char
*
PoolTypeConverter
<
uint16_t
>::
AsmTag
=
".short"
;
const
char
*
PoolTypeConverter
<
uint16_t
>::
PrintfString
=
"0x%x"
;
// Add converter for int type constant pooling
template
<>
struct
PoolTypeConverter
<
uint8_t
>
{
using
PrimitiveIntType
=
uint32_t
;
using
IceType
=
ConstantInteger32
;
static
const
Type
Ty
=
IceType_i8
;
static
const
char
*
TypeName
;
static
const
char
*
AsmTag
;
static
const
char
*
PrintfString
;
};
const
char
*
PoolTypeConverter
<
uint8_t
>::
TypeName
=
"i8"
;
const
char
*
PoolTypeConverter
<
uint8_t
>::
AsmTag
=
".byte"
;
const
char
*
PoolTypeConverter
<
uint8_t
>::
PrintfString
=
"0x%x"
;
}
// end of anonymous namespace
template
<
typename
T
>
void
TargetDataX8664
::
emitConstantPool
(
GlobalContext
*
Ctx
)
{
if
(
!
BuildDefs
::
dump
())
return
;
Ostream
&
Str
=
Ctx
->
getStrEmit
();
Type
Ty
=
T
::
Ty
;
SizeT
Align
=
typeAlignInBytes
(
Ty
);
ConstantList
Pool
=
Ctx
->
getConstantPool
(
Ty
);
Str
<<
"
\t
.section
\t
.rodata.cst"
<<
Align
<<
",
\"
aM
\"
,@progbits,"
<<
Align
<<
"
\n
"
;
Str
<<
"
\t
.align
\t
"
<<
Align
<<
"
\n
"
;
// If reorder-pooled-constants option is set to true, we need to shuffle the
// constant pool before emitting it.
if
(
Ctx
->
getFlags
().
shouldReorderPooledConstants
())
{
// Use the constant's kind value as the salt for creating random number
// generator.
Operand
::
OperandKind
K
=
(
*
Pool
.
begin
())
->
getKind
();
RandomNumberGenerator
RNG
(
Ctx
->
getFlags
().
getRandomSeed
(),
RPE_PooledConstantReordering
,
K
);
RandomShuffle
(
Pool
.
begin
(),
Pool
.
end
(),
[
&
RNG
](
uint64_t
N
)
{
return
(
uint32_t
)
RNG
.
next
(
N
);
});
}
for
(
Constant
*
C
:
Pool
)
{
if
(
!
C
->
getShouldBePooled
())
continue
;
auto
*
Const
=
llvm
::
cast
<
typename
T
::
IceType
>
(
C
);
typename
T
::
IceType
::
PrimType
Value
=
Const
->
getValue
();
// Use memcpy() to copy bits from Value into RawValue in a way that avoids
// breaking strict-aliasing rules.
typename
T
::
PrimitiveIntType
RawValue
;
memcpy
(
&
RawValue
,
&
Value
,
sizeof
(
Value
));
char
buf
[
30
];
int
CharsPrinted
=
snprintf
(
buf
,
llvm
::
array_lengthof
(
buf
),
T
::
PrintfString
,
RawValue
);
assert
(
CharsPrinted
>=
0
&&
(
size_t
)
CharsPrinted
<
llvm
::
array_lengthof
(
buf
));
(
void
)
CharsPrinted
;
// avoid warnings if asserts are disabled
Const
->
emitPoolLabel
(
Str
,
Ctx
);
Str
<<
":
\n\t
"
<<
T
::
AsmTag
<<
"
\t
"
<<
buf
<<
"
\t
/* "
<<
T
::
TypeName
<<
" "
<<
Value
<<
" */
\n
"
;
}
}
void
TargetDataX8664
::
lowerConstants
()
{
if
(
Ctx
->
getFlags
().
getDisableTranslation
())
return
;
// No need to emit constants from the int pool since (for x86) they are
// embedded as immediates in the instructions, just emit float/double.
switch
(
Ctx
->
getFlags
().
getOutFileType
())
{
case
FT_Elf
:
{
ELFObjectWriter
*
Writer
=
Ctx
->
getObjectWriter
();
Writer
->
writeConstantPool
<
ConstantInteger32
>
(
IceType_i8
);
Writer
->
writeConstantPool
<
ConstantInteger32
>
(
IceType_i16
);
Writer
->
writeConstantPool
<
ConstantInteger32
>
(
IceType_i32
);
Writer
->
writeConstantPool
<
ConstantFloat
>
(
IceType_f32
);
Writer
->
writeConstantPool
<
ConstantDouble
>
(
IceType_f64
);
}
break
;
case
FT_Asm
:
case
FT_Iasm
:
{
OstreamLocker
L
(
Ctx
);
emitConstantPool
<
PoolTypeConverter
<
uint8_t
>>
(
Ctx
);
emitConstantPool
<
PoolTypeConverter
<
uint16_t
>>
(
Ctx
);
emitConstantPool
<
PoolTypeConverter
<
uint32_t
>>
(
Ctx
);
emitConstantPool
<
PoolTypeConverter
<
float
>>
(
Ctx
);
emitConstantPool
<
PoolTypeConverter
<
double
>>
(
Ctx
);
}
break
;
}
}
void
TargetDataX8664
::
lowerJumpTables
()
{
const
bool
IsPIC
=
Ctx
->
getFlags
().
getUseNonsfi
();
switch
(
Ctx
->
getFlags
().
getOutFileType
())
{
case
FT_Elf
:
{
ELFObjectWriter
*
Writer
=
Ctx
->
getObjectWriter
();
for
(
const
JumpTableData
&
JumpTable
:
Ctx
->
getJumpTables
())
Writer
->
writeJumpTable
(
JumpTable
,
TargetX8664
::
Traits
::
FK_Abs
,
IsPIC
);
}
break
;
case
FT_Asm
:
// Already emitted from Cfg
break
;
case
FT_Iasm
:
{
if
(
!
BuildDefs
::
dump
())
return
;
Ostream
&
Str
=
Ctx
->
getStrEmit
();
for
(
const
JumpTableData
&
JT
:
Ctx
->
getJumpTables
())
{
Str
<<
"
\t
.section
\t
.rodata."
<<
JT
.
getFunctionName
()
<<
"$jumptable,
\"
a
\"
,@progbits
\n
"
;
Str
<<
"
\t
.align
\t
"
<<
typeWidthInBytes
(
getPointerType
())
<<
"
\n
"
;
Str
<<
InstJumpTable
::
makeName
(
JT
.
getFunctionName
(),
JT
.
getId
())
<<
":"
;
// On X8664 ILP32 pointers are 32-bit hence the use of .long
for
(
intptr_t
TargetOffset
:
JT
.
getTargetOffsets
())
Str
<<
"
\n\t
.long
\t
"
<<
JT
.
getFunctionName
()
<<
"+"
<<
TargetOffset
;
Str
<<
"
\n
"
;
}
}
break
;
}
}
void
TargetDataX8664
::
lowerGlobals
(
const
VariableDeclarationList
&
Vars
,
const
IceString
&
SectionSuffix
)
{
const
bool
IsPIC
=
Ctx
->
getFlags
().
getUseNonsfi
();
switch
(
Ctx
->
getFlags
().
getOutFileType
())
{
case
FT_Elf
:
{
ELFObjectWriter
*
Writer
=
Ctx
->
getObjectWriter
();
Writer
->
writeDataSection
(
Vars
,
TargetX8664
::
Traits
::
FK_Abs
,
SectionSuffix
,
IsPIC
);
}
break
;
case
FT_Asm
:
case
FT_Iasm
:
{
const
IceString
&
TranslateOnly
=
Ctx
->
getFlags
().
getTranslateOnly
();
OstreamLocker
L
(
Ctx
);
for
(
const
VariableDeclaration
*
Var
:
Vars
)
{
if
(
GlobalContext
::
matchSymbolName
(
Var
->
getName
(),
TranslateOnly
))
{
emitGlobal
(
*
Var
,
SectionSuffix
);
}
}
}
break
;
}
}
// In some cases, there are x-macros tables for both high-level and low-level
// instructions/operands that use the same enum key value. The tables are kept
// separate to maintain a proper separation between abstraction layers. There
...
...
src/IceTargetLoweringX8664.h
View file @
6b80cf10
...
...
@@ -34,9 +34,6 @@ class TargetX8664 final : public X8664::TargetX86Base<X8664::Traits> {
TargetX8664
(
const
TargetX8664
&
)
=
delete
;
TargetX8664
&
operator
=
(
const
TargetX8664
&
)
=
delete
;
void
emitJumpTable
(
const
Cfg
*
Func
,
const
InstJumpTable
*
JumpTable
)
const
override
;
public
:
~
TargetX8664
()
=
default
;
...
...
@@ -49,12 +46,9 @@ public:
return
makeUnique
<
X8664
::
AssemblerX8664
>
(
EmitAddrSizeOverridePrefix
);
}
bool
needSandboxing
()
const
{
return
NeedSandboxing
;
}
protected
:
void
_add_sp
(
Operand
*
Adjustment
);
void
_mov_sp
(
Operand
*
NewValue
);
void
_push_rbp
();
Traits
::
X86OperandMem
*
_sandbox_mem_reference
(
X86OperandMem
*
Mem
);
void
_sub_sp
(
Operand
*
Adjustment
);
void
_link_bp
();
...
...
@@ -72,8 +66,9 @@ private:
ENABLE_MAKE_UNIQUE
;
friend
class
X8664
::
TargetX86Base
<
X8664
::
Traits
>
;
explicit
TargetX8664
(
Cfg
*
Func
)
:
::
Ice
::
X8664
::
TargetX86Base
<
X8664
::
Traits
>
(
Func
)
{}
explicit
TargetX8664
(
Cfg
*
Func
)
:
TargetX86Base
(
Func
)
{}
void
_push_rbp
();
Operand
*
createNaClReadTPSrcOperand
()
{
Variable
*
TDB
=
makeReg
(
IceType_i32
);
...
...
@@ -83,49 +78,6 @@ private:
}
};
class
TargetDataX8664
:
public
TargetDataLowering
{
TargetDataX8664
()
=
delete
;
TargetDataX8664
(
const
TargetDataX8664
&
)
=
delete
;
TargetDataX8664
&
operator
=
(
const
TargetDataX8664
&
)
=
delete
;
public
:
~
TargetDataX8664
()
override
=
default
;
static
std
::
unique_ptr
<
TargetDataLowering
>
create
(
GlobalContext
*
Ctx
)
{
return
makeUnique
<
TargetDataX8664
>
(
Ctx
);
}
void
lowerGlobals
(
const
VariableDeclarationList
&
Vars
,
const
IceString
&
SectionSuffix
)
override
;
void
lowerConstants
()
override
;
void
lowerJumpTables
()
override
;
private
:
ENABLE_MAKE_UNIQUE
;
explicit
TargetDataX8664
(
GlobalContext
*
Ctx
)
:
TargetDataLowering
(
Ctx
)
{}
template
<
typename
T
>
static
void
emitConstantPool
(
GlobalContext
*
Ctx
);
};
class
TargetHeaderX8664
:
public
TargetHeaderLowering
{
TargetHeaderX8664
()
=
delete
;
TargetHeaderX8664
(
const
TargetHeaderX8664
&
)
=
delete
;
TargetHeaderX8664
&
operator
=
(
const
TargetHeaderX8664
&
)
=
delete
;
public
:
~
TargetHeaderX8664
()
=
default
;
static
std
::
unique_ptr
<
TargetHeaderLowering
>
create
(
GlobalContext
*
Ctx
)
{
return
makeUnique
<
TargetHeaderX8664
>
(
Ctx
);
}
private
:
ENABLE_MAKE_UNIQUE
;
explicit
TargetHeaderX8664
(
GlobalContext
*
Ctx
)
:
TargetHeaderLowering
(
Ctx
)
{}
};
}
// end of namespace X8664
}
// end of namespace Ice
...
...
src/IceTargetLoweringX86Base.h
View file @
6b80cf10
...
...
@@ -298,6 +298,10 @@ protected:
virtual
Variable
*
moveReturnValueToRegister
(
Operand
*
Value
,
Type
ReturnType
)
=
0
;
/// Emit a jump table to the constant pool.
void
emitJumpTable
(
const
Cfg
*
Func
,
const
InstJumpTable
*
JumpTable
)
const
override
;
/// Emit a fake use of esp to make sure esp stays alive for the entire
/// function. Otherwise some esp adjustments get dead-code eliminated.
void
keepEspLiveAtExit
()
{
...
...
@@ -1020,6 +1024,51 @@ private:
static
FixupKind
PcRelFixup
;
static
FixupKind
AbsFixup
;
};
template
<
typename
TraitsType
>
class
TargetDataX86
final
:
public
TargetDataLowering
{
using
Traits
=
TraitsType
;
TargetDataX86
()
=
delete
;
TargetDataX86
(
const
TargetDataX86
&
)
=
delete
;
TargetDataX86
&
operator
=
(
const
TargetDataX86
&
)
=
delete
;
public
:
~
TargetDataX86
()
override
=
default
;
static
std
::
unique_ptr
<
TargetDataLowering
>
create
(
GlobalContext
*
Ctx
)
{
return
makeUnique
<
TargetDataX86
>
(
Ctx
);
}
void
lowerGlobals
(
const
VariableDeclarationList
&
Vars
,
const
IceString
&
SectionSuffix
)
override
;
void
lowerConstants
()
override
;
void
lowerJumpTables
()
override
;
private
:
ENABLE_MAKE_UNIQUE
;
explicit
TargetDataX86
(
GlobalContext
*
Ctx
)
:
TargetDataLowering
(
Ctx
){};
template
<
typename
T
>
static
void
emitConstantPool
(
GlobalContext
*
Ctx
);
};
class
TargetHeaderX86
:
public
TargetHeaderLowering
{
TargetHeaderX86
()
=
delete
;
TargetHeaderX86
(
const
TargetHeaderX86
&
)
=
delete
;
TargetHeaderX86
&
operator
=
(
const
TargetHeaderX86
&
)
=
delete
;
public
:
~
TargetHeaderX86
()
=
default
;
static
std
::
unique_ptr
<
TargetHeaderLowering
>
create
(
GlobalContext
*
Ctx
)
{
return
makeUnique
<
TargetHeaderX86
>
(
Ctx
);
}
private
:
ENABLE_MAKE_UNIQUE
;
explicit
TargetHeaderX86
(
GlobalContext
*
Ctx
)
:
TargetHeaderLowering
(
Ctx
)
{}
};
}
// end of namespace X86NAMESPACE
}
// end of namespace Ice
...
...
src/IceTargetLoweringX86BaseImpl.h
View file @
6b80cf10
...
...
@@ -33,6 +33,58 @@
#include <stack>
namespace
Ice
{
namespace
X86
{
template
<
typename
T
>
struct
PoolTypeConverter
{};
template
<>
struct
PoolTypeConverter
<
float
>
{
using
PrimitiveIntType
=
uint32_t
;
using
IceType
=
ConstantFloat
;
static
const
Type
Ty
=
IceType_f32
;
static
const
char
*
TypeName
;
static
const
char
*
AsmTag
;
static
const
char
*
PrintfString
;
};
template
<>
struct
PoolTypeConverter
<
double
>
{
using
PrimitiveIntType
=
uint64_t
;
using
IceType
=
ConstantDouble
;
static
const
Type
Ty
=
IceType_f64
;
static
const
char
*
TypeName
;
static
const
char
*
AsmTag
;
static
const
char
*
PrintfString
;
};
// Add converter for int type constant pooling
template
<>
struct
PoolTypeConverter
<
uint32_t
>
{
using
PrimitiveIntType
=
uint32_t
;
using
IceType
=
ConstantInteger32
;
static
const
Type
Ty
=
IceType_i32
;
static
const
char
*
TypeName
;
static
const
char
*
AsmTag
;
static
const
char
*
PrintfString
;
};
// Add converter for int type constant pooling
template
<>
struct
PoolTypeConverter
<
uint16_t
>
{
using
PrimitiveIntType
=
uint32_t
;
using
IceType
=
ConstantInteger32
;
static
const
Type
Ty
=
IceType_i16
;
static
const
char
*
TypeName
;
static
const
char
*
AsmTag
;
static
const
char
*
PrintfString
;
};
// Add converter for int type constant pooling
template
<>
struct
PoolTypeConverter
<
uint8_t
>
{
using
PrimitiveIntType
=
uint32_t
;
using
IceType
=
ConstantInteger32
;
static
const
Type
Ty
=
IceType_i8
;
static
const
char
*
TypeName
;
static
const
char
*
AsmTag
;
static
const
char
*
PrintfString
;
};
}
// end of namespace X86
namespace
X86NAMESPACE
{
/// A helper class to ease the settings of RandomizationPoolingPause to disable
...
...
@@ -7229,6 +7281,156 @@ TargetX86Base<TraitsType>::randomizeOrPoolImmediate(X86OperandMem *MemOperand,
}
}
}
template
<
typename
TraitsType
>
void
TargetX86Base
<
TraitsType
>::
emitJumpTable
(
const
Cfg
*
Func
,
const
InstJumpTable
*
JumpTable
)
const
{
if
(
!
BuildDefs
::
dump
())
return
;
Ostream
&
Str
=
Ctx
->
getStrEmit
();
const
bool
UseNonsfi
=
Ctx
->
getFlags
().
getUseNonsfi
();
const
IceString
MangledName
=
Ctx
->
mangleName
(
Func
->
getFunctionName
());
const
IceString
Prefix
=
UseNonsfi
?
".data.rel.ro."
:
".rodata."
;
Str
<<
"
\t
.section
\t
"
<<
Prefix
<<
MangledName
<<
"$jumptable,
\"
a
\"
,@progbits
\n
"
;
Str
<<
"
\t
.align
\t
"
<<
typeWidthInBytes
(
getPointerType
())
<<
"
\n
"
;
Str
<<
InstJumpTable
::
makeName
(
MangledName
,
JumpTable
->
getId
())
<<
":"
;
// On X86 ILP32 pointers are 32-bit hence the use of .long
for
(
SizeT
I
=
0
;
I
<
JumpTable
->
getNumTargets
();
++
I
)
Str
<<
"
\n\t
.long
\t
"
<<
JumpTable
->
getTarget
(
I
)
->
getAsmName
();
Str
<<
"
\n
"
;
}
template
<
typename
TraitsType
>
template
<
typename
T
>
void
TargetDataX86
<
TraitsType
>::
emitConstantPool
(
GlobalContext
*
Ctx
)
{
if
(
!
BuildDefs
::
dump
())
return
;
Ostream
&
Str
=
Ctx
->
getStrEmit
();
Type
Ty
=
T
::
Ty
;
SizeT
Align
=
typeAlignInBytes
(
Ty
);
ConstantList
Pool
=
Ctx
->
getConstantPool
(
Ty
);
Str
<<
"
\t
.section
\t
.rodata.cst"
<<
Align
<<
",
\"
aM
\"
,@progbits,"
<<
Align
<<
"
\n
"
;
Str
<<
"
\t
.align
\t
"
<<
Align
<<
"
\n
"
;
// If reorder-pooled-constants option is set to true, we need to shuffle the
// constant pool before emitting it.
if
(
Ctx
->
getFlags
().
shouldReorderPooledConstants
()
&&
!
Pool
.
empty
())
{
// Use the constant's kind value as the salt for creating random number
// generator.
Operand
::
OperandKind
K
=
(
*
Pool
.
begin
())
->
getKind
();
RandomNumberGenerator
RNG
(
Ctx
->
getFlags
().
getRandomSeed
(),
RPE_PooledConstantReordering
,
K
);
RandomShuffle
(
Pool
.
begin
(),
Pool
.
end
(),
[
&
RNG
](
uint64_t
N
)
{
return
(
uint32_t
)
RNG
.
next
(
N
);
});
}
for
(
Constant
*
C
:
Pool
)
{
if
(
!
C
->
getShouldBePooled
())
continue
;
auto
*
Const
=
llvm
::
cast
<
typename
T
::
IceType
>
(
C
);
typename
T
::
IceType
::
PrimType
Value
=
Const
->
getValue
();
// Use memcpy() to copy bits from Value into RawValue in a way that avoids
// breaking strict-aliasing rules.
typename
T
::
PrimitiveIntType
RawValue
;
memcpy
(
&
RawValue
,
&
Value
,
sizeof
(
Value
));
char
buf
[
30
];
int
CharsPrinted
=
snprintf
(
buf
,
llvm
::
array_lengthof
(
buf
),
T
::
PrintfString
,
RawValue
);
assert
(
CharsPrinted
>=
0
);
assert
((
size_t
)
CharsPrinted
<
llvm
::
array_lengthof
(
buf
));
(
void
)
CharsPrinted
;
// avoid warnings if asserts are disabled
Const
->
emitPoolLabel
(
Str
,
Ctx
);
Str
<<
":
\n\t
"
<<
T
::
AsmTag
<<
"
\t
"
<<
buf
<<
"
\t
/* "
<<
T
::
TypeName
<<
" "
<<
Value
<<
" */
\n
"
;
}
}
template
<
typename
TraitsType
>
void
TargetDataX86
<
TraitsType
>::
lowerConstants
()
{
if
(
Ctx
->
getFlags
().
getDisableTranslation
())
return
;
switch
(
Ctx
->
getFlags
().
getOutFileType
())
{
case
FT_Elf
:
{
ELFObjectWriter
*
Writer
=
Ctx
->
getObjectWriter
();
Writer
->
writeConstantPool
<
ConstantInteger32
>
(
IceType_i8
);
Writer
->
writeConstantPool
<
ConstantInteger32
>
(
IceType_i16
);
Writer
->
writeConstantPool
<
ConstantInteger32
>
(
IceType_i32
);
Writer
->
writeConstantPool
<
ConstantFloat
>
(
IceType_f32
);
Writer
->
writeConstantPool
<
ConstantDouble
>
(
IceType_f64
);
}
break
;
case
FT_Asm
:
case
FT_Iasm
:
{
OstreamLocker
L
(
Ctx
);
emitConstantPool
<
PoolTypeConverter
<
uint8_t
>>
(
Ctx
);
emitConstantPool
<
PoolTypeConverter
<
uint16_t
>>
(
Ctx
);
emitConstantPool
<
PoolTypeConverter
<
uint32_t
>>
(
Ctx
);
emitConstantPool
<
PoolTypeConverter
<
float
>>
(
Ctx
);
emitConstantPool
<
PoolTypeConverter
<
double
>>
(
Ctx
);
}
break
;
}
}
template
<
typename
TraitsType
>
void
TargetDataX86
<
TraitsType
>::
lowerJumpTables
()
{
const
bool
IsPIC
=
Ctx
->
getFlags
().
getUseNonsfi
();
switch
(
Ctx
->
getFlags
().
getOutFileType
())
{
case
FT_Elf
:
{
ELFObjectWriter
*
Writer
=
Ctx
->
getObjectWriter
();
for
(
const
JumpTableData
&
JT
:
Ctx
->
getJumpTables
())
Writer
->
writeJumpTable
(
JT
,
Traits
::
FK_Abs
,
IsPIC
);
}
break
;
case
FT_Asm
:
// Already emitted from Cfg
break
;
case
FT_Iasm
:
{
if
(
!
BuildDefs
::
dump
())
return
;
Ostream
&
Str
=
Ctx
->
getStrEmit
();
const
IceString
Prefix
=
IsPIC
?
".data.rel.ro."
:
".rodata."
;
for
(
const
JumpTableData
&
JT
:
Ctx
->
getJumpTables
())
{
Str
<<
"
\t
.section
\t
"
<<
Prefix
<<
JT
.
getFunctionName
()
<<
"$jumptable,
\"
a
\"
,@progbits
\n
"
;
Str
<<
"
\t
.align
\t
"
<<
typeWidthInBytes
(
getPointerType
())
<<
"
\n
"
;
Str
<<
InstJumpTable
::
makeName
(
JT
.
getFunctionName
(),
JT
.
getId
())
<<
":"
;
// On X8664 ILP32 pointers are 32-bit hence the use of .long
for
(
intptr_t
TargetOffset
:
JT
.
getTargetOffsets
())
Str
<<
"
\n\t
.long
\t
"
<<
JT
.
getFunctionName
()
<<
"+"
<<
TargetOffset
;
Str
<<
"
\n
"
;
}
}
break
;
}
}
template
<
typename
TraitsType
>
void
TargetDataX86
<
TraitsType
>::
lowerGlobals
(
const
VariableDeclarationList
&
Vars
,
const
IceString
&
SectionSuffix
)
{
const
bool
IsPIC
=
Ctx
->
getFlags
().
getUseNonsfi
();
switch
(
Ctx
->
getFlags
().
getOutFileType
())
{
case
FT_Elf
:
{
ELFObjectWriter
*
Writer
=
Ctx
->
getObjectWriter
();
Writer
->
writeDataSection
(
Vars
,
Traits
::
FK_Abs
,
SectionSuffix
,
IsPIC
);
}
break
;
case
FT_Asm
:
case
FT_Iasm
:
{
const
IceString
&
TranslateOnly
=
Ctx
->
getFlags
().
getTranslateOnly
();
OstreamLocker
L
(
Ctx
);
for
(
const
VariableDeclaration
*
Var
:
Vars
)
{
if
(
GlobalContext
::
matchSymbolName
(
Var
->
getName
(),
TranslateOnly
))
{
emitGlobal
(
*
Var
,
SectionSuffix
);
}
}
}
break
;
}
}
}
// end of namespace X86NAMESPACE
}
// end of namespace Ice
...
...
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