Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
latte
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
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
zygzagZ
latte
Commits
e694f348
Commit
e694f348
authored
Jan 09, 2021
by
zygzagZ
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
WIP asm
parent
bb0ba170
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
171 additions
and
47 deletions
+171
-47
Compiler.cpp
src/Compiler.cpp
+91
-13
Compiler.h
src/Compiler.h
+57
-12
BasicBlock.h
src/codeGen/BasicBlock.h
+22
-21
RegisterAllocator.cpp
src/codeGen/RegisterAllocator.cpp
+1
-1
No files found.
src/Compiler.cpp
View file @
e694f348
...
...
@@ -65,6 +65,17 @@ void Compiler::compileFunction(const FunctionInfoPtr& f) {
}
printFunction
(
quadEnv
);
// for (auto &b : quadEnv.blocks) {
// for (auto &q : b->quads) {
// q->generateAsm(*this);
// }
// }
for
(
auto
&
t
:
temps
)
t
->
localOffset
=
0
;
for
(
auto
&
v
:
localInfos
)
v
->
localOffset
=
0
;
temps
.
clear
();
localInfos
.
clear
();
}
void
Compiler
::
printFunction
(
QuadrupleGenerator
::
Result
quadEnv
)
{
...
...
@@ -108,6 +119,7 @@ void Compiler::printFunction(QuadrupleGenerator::Result quadEnv) {
for
(
auto
var
:
q
->
aliveAfter
)
buf
<<
var
->
name
<<
" "
;
buf
<<
endl
;
q
->
generateAsm
(
*
this
);
}
}
if
(
!
b
->
flow
.
use
.
empty
())
{
...
...
@@ -128,17 +140,25 @@ void Compiler::printFunction(QuadrupleGenerator::Result quadEnv) {
}
}
Compiler
::
regs
=
{
"eax"
,
"ebx"
,
"ecx"
,
"edx"
,
"esi"
,
"edi"
};
const
char
*
const
Compiler
::
regs
[
6
]
=
{
"eax"
,
"ebx"
,
"ecx"
,
"edx"
,
"esi"
,
"edi"
};
string
Compiler
::
getRef
(
VariablePtr
&
v
)
{
if
(
v
->
registerColor
==
-
1
)
{
if
(
!
v
->
localOffset
)
{
temps
.
emplace
(
v
);
v
->
localOffset
=
4
*
temps
.
size
();
if
(
v
->
info
)
{
if
(
!
v
->
info
->
localOffset
)
{
localInfos
.
emplace
(
v
->
info
);
v
->
info
->
localOffset
=
4
*
(
temps
.
size
()
+
localInfos
.
size
());
}
v
->
localOffset
=
v
->
info
->
localOffset
;
}
else
{
temps
.
emplace
(
v
);
v
->
localOffset
=
4
*
(
temps
.
size
()
+
localInfos
.
size
());
}
}
return
to_string
(
v
->
localOffset
)
+
"(ebp)"
;
return
to_string
(
v
->
localOffset
)
+
"(
%
ebp)"
;
}
else
{
return
regs
[
v
->
registerColor
+
1
]
;
return
Register
(
v
)
;
}
}
...
...
@@ -174,32 +194,90 @@ void Compiler::generateQCall(QCall &q) {
void
Compiler
::
generateQParam
(
QParam
&
q
)
{
// return Quadruple::generateAsm();
auto
reg
=
Register
(
q
.
param
);
if
(
q
.
num
<
0
)
{
auto
offset
=
4
*
q
.
num
;
if
(
reg
==
0
)
{
q
.
param
->
localOffset
=
offset
;
}
else
{
append
(
"MOVL"
,
to_string
(
offset
)
+
"(%ebp)"
);
}
}
else
{
append
(
"PUSHL"
,
getRef
(
q
.
param
));
}
}
void
Compiler
::
generateQJump
(
QJump
&
q
)
{
// return Quadruple::generateAsm();
// append("JMP", q.block.la)
}
void
Compiler
::
generateQAssign
(
QAssign
&
q
)
{
string
tg
=
regs
[
q
.
loc
->
registerColor
+
1
]
;
Register
tg
(
q
.
loc
)
;
if
(
q
.
args
.
size
()
==
1
)
{
auto
&
arg
=
q
.
args
[
0
];
switch
(
q
.
op
.
op
)
{
case
Op
:
:
Not
:
{
buf
<<
""
return
;
auto
reg
=
Register
(
arg
);
if
(
reg
==
0
)
{
// avoids extra MOV when arg is already in register
moveTo
(
arg
,
tg
);
reg
=
tg
;
}
append
(
"TEST"
,
reg
,
reg
);
append
(
"SETZ"
,
tg
);
break
;
}
case
Op
:
:
Copy
:
{
if
(
arg
->
constExpr
)
{
// TODO
}
else
{
moveTo
(
arg
,
tg
);
}
break
;
}
case
Op
:
:
Neg
:
{
moveTo
(
arg
,
tg
);
append
(
"NEG"
,
tg
);
break
;
}
default:
throw
runtime_error
(
"Unexpected operand"
);
}
}
else
{
buf
<<
"movl %"
<<
tg
<<
" "
;
auto
&
i
=
q
.
args
[
0
],
&
j
=
q
.
args
[
1
];
buf
<<
getRef
(
i
)
<<
endl
;
buf
<<
getOpName
(
q
.
op
)
<<
" %"
<<
tg
<<
" "
<<
getRef
(
i
)
<<
endl
;
if
(
q
.
op
==
Op
::
Div
||
q
.
op
==
Op
::
Mod
)
{
auto
edx
=
Register
(
"edx"
);
bool
backupEdx
=
edx
!=
tg
&&
edx
!=
Register
(
i
);
if
(
backupEdx
)
append
(
"MOVL"
,
edx
,
"4(%esp)"
);
auto
jLoc
=
edx
!=
Register
(
j
)
?
getRef
(
j
)
:
"4(%esp)"
;
moveTo
(
i
,
0
);
append
(
"CLTD"
);
// edx lost
append
(
"IDIVL"
,
jLoc
);
moveTo
(
q
.
op
==
Op
::
Mod
?
edx
:
0
,
getRef
(
q
.
loc
));
// restore unnecessary if j was in edx and becomes dead and was NOT coalesced
if
(
backupEdx
)
append
(
"MOVL"
,
"4(%esp)"
,
edx
);
return
;
}
else
if
(
q
.
op
<
Op
::
CMP
)
{
moveTo
(
i
,
tg
);
append
(
q
.
op
,
getRef
(
i
),
tg
);
}
else
{
auto
loc
=
getRef
(
i
);
if
(
Register
(
i
)
==
0
&&
Register
(
j
)
==
0
)
{
moveTo
(
i
,
0
);
loc
=
"%eax"
;
}
append
(
"CMPL"
,
loc
,
getRef
(
j
));
append
(
q
.
op
,
tg
);
}
}
if
(
tg
==
0
)
{
append
(
"MOVL"
,
tg
,
getRef
(
q
.
loc
));
}
}
void
Compiler
::
generateQLabel
(
QLabel
&
q
)
{
// return Quadruple::generateAsm();
}
\ No newline at end of file
}
src/Compiler.h
View file @
e694f348
...
...
@@ -50,6 +50,17 @@ private:
void
compileFunction
(
const
FunctionInfoPtr
&
f
);
void
printFunction
(
QuadrupleGenerator
::
Result
quadEnv
);
class
Register
{
public:
Register
(
string
n
)
:
name
(
std
::
move
(
n
))
{};
Register
(
int
n
)
{
name
=
Compiler
::
regs
[
n
];
}
Register
(
const
VariablePtr
&
v
)
{
name
=
Compiler
::
regs
[
v
->
registerColor
+
1
];
}
string
name
;
operator
string
()
{
return
"%"
+
name
;
}
bool
operator
==
(
const
Register
&
other
)
const
{
return
name
==
other
.
name
;
}
bool
operator
!=
(
const
Register
&
other
)
const
{
return
name
!=
other
.
name
;
}
};
static
std
::
string
mangleFunctionName
(
const
FunctionInfoPtr
&
f
)
{
if
(
auto
c
=
f
->
klass
.
lock
())
{
return
c
->
name
+
"::"
+
f
->
name
;
...
...
@@ -59,24 +70,58 @@ private:
string
getRef
(
VariablePtr
&
v
);
static
const
char
*
*
regs
;
static
const
char
*
const
regs
[
6
]
;
static
string
getOpName
(
Quadruple
::
Op
op
)
{
switch
(
op
.
op
)
{
case
Op
:
:
Plus
:
return
"addl"
;
case
Op
:
:
Minus
:
return
"subl"
;
case
Op
:
:
Mul
:
return
"mull"
;
case
Op
:
:
Div
:
return
"divl"
;
case
Op
:
:
Mod
:
return
"divl"
;
default:
return
""
;
case
Op
:
:
Plus
:
return
"ADDL"
;
case
Op
:
:
Minus
:
return
"SUBL"
;
case
Op
:
:
Mul
:
return
"IMULL"
;
case
Op
:
:
Div
:
case
Op
:
:
Mod
:
throw
runtime_error
(
"Impossible to handle division with default"
);
case
Op
:
:
LT
:
return
"SETL"
;
case
Op
:
:
LE
:
return
"SETLE"
;
case
Op
:
:
EQ
:
return
"SETE"
;
case
Op
:
:
NEQ
:
return
"SETNE"
;
case
Op
:
:
GE
:
return
"SETGE"
;
case
Op
:
:
GT
:
return
"SETG"
;
default:
return
"Op"
+
to_string
(
op
.
op
)
+
"?"
;
}
}
void
moveTo
(
VariablePtr
&
v
,
Register
tg
)
{
if
(
v
->
constExpr
)
{
append
(
"MOVL"
,
"$"
+
to_string
(
v
->
val
),
tg
);
return
;
}
auto
reg
=
Register
(
v
);
if
(
reg
==
0
)
{
append
(
"MOVL"
,
getRef
(
v
),
tg
);
}
else
if
(
reg
!=
tg
)
{
append
(
"MOVL"
,
reg
,
tg
);
}
}
void
moveTo
(
Register
reg
,
Register
tg
)
{
if
(
reg
!=
tg
)
{
append
(
"MOVL"
,
reg
,
tg
);
}
}
Register
moveToAnyRegister
(
VariablePtr
&
v
)
{
auto
reg
=
Register
(
v
);
if
(
reg
==
0
)
{
append
(
"MOVL"
,
getRef
(
v
),
reg
);
}
return
reg
;
}
void
append
(
Quadruple
::
Op
op
,
string
op1
,
string
op2
=
""
,
string
op3
=
""
)
{
return
append
(
getOpName
(
op
),
op1
,
op2
,
op3
);
}
string
moveToAnyRegister
(
VariablePtr
&
v
)
{
if
(
v
->
registerColor
==
-
1
)
{
buf
<<
"movl %eax "
<<
getRef
(
v
)
<<
endl
;
return
"eax"
;
}
else
return
regs
[
v
->
registerColor
+
1
];
void
append
(
string
cmd
,
string
op1
=
""
,
string
op2
=
""
,
string
op3
=
""
)
{
buf
<<
"
\t
"
<<
cmd
<<
" "
<<
op1
<<
" "
<<
op2
<<
" "
<<
op3
<<
endl
;
}
};
...
...
src/codeGen/BasicBlock.h
View file @
e694f348
...
...
@@ -13,26 +13,6 @@ using namespace std;
class
BasicBlock
:
public
std
::
enable_shared_from_this
<
BasicBlock
>
{
public:
struct
FlowAnalysisData
{
set
<
VariablePtr
>
in
,
out
,
def
,
use
;
BasicBlock
*
b
{};
void
addUse
(
const
VariablePtr
&
v
)
{
if
(
!
def
.
contains
(
v
))
use
.
emplace
(
v
);
}
void
addDef
(
const
VariablePtr
&
v
)
{
def
.
emplace
(
v
);
use
.
erase
(
v
);
}
[[
nodiscard
]]
set
<
VariablePtr
>
inForBlock
(
const
BasicBlockPtr
&
q
)
const
{
set
<
VariablePtr
>
ret
;
for
(
const
auto
&
var
:
b
->
findPhi
(
q
))
{
ret
.
emplace
(
var
.
second
);
}
return
in
+
ret
;
}
};
BasicBlock
()
{
phi
=
make_shared
<
QPhi
>
();
flow
.
b
=
this
;
...
...
@@ -42,7 +22,6 @@ public:
vector
<
QuadruplePtr
>
afterInit
;
vector
<
BasicBlockPtr
>
in
,
out
;
shared_ptr
<
QPhi
>
phi
;
FlowAnalysisData
flow
;
void
append
(
const
BasicBlockPtr
&
after
)
{
out
.
push_back
(
after
);
after
->
in
.
push_back
(
shared_from_this
());
...
...
@@ -77,6 +56,28 @@ public:
}
void
finishQuads
();
struct
FlowAnalysisData
{
set
<
VariablePtr
>
in
,
out
,
def
,
use
;
BasicBlock
*
b
{};
void
addUse
(
const
VariablePtr
&
v
)
{
if
(
!
def
.
contains
(
v
))
use
.
emplace
(
v
);
}
void
addDef
(
const
VariablePtr
&
v
)
{
def
.
emplace
(
v
);
use
.
erase
(
v
);
}
[[
nodiscard
]]
set
<
VariablePtr
>
inForBlock
(
const
BasicBlockPtr
&
q
)
const
{
set
<
VariablePtr
>
ret
;
for
(
const
auto
&
var
:
b
->
findPhi
(
q
))
{
ret
.
emplace
(
var
.
second
);
}
return
in
+
ret
;
}
};
FlowAnalysisData
flow
;
};
...
...
src/codeGen/RegisterAllocator.cpp
View file @
e694f348
...
...
@@ -69,7 +69,7 @@ void RegisterAllocator::buildGraph() {
set
<
VariablePtr
>
alive
=
b
->
flow
.
in
;
for
(
const
auto
&
q
:
b
->
quads
)
{
if
(
auto
assign
=
dynamic_pointer_cast
<
QAssign
>
(
q
))
{
if
(
assign
->
op
==
Quadruple
::
Op
::
Copy
)
{
if
(
assign
->
op
==
Quadruple
::
Op
::
Copy
&&
!
assign
->
args
[
0
]
->
constExpr
)
{
graph
.
addAssign
(
assign
->
loc
,
assign
->
args
[
0
]);
g2
.
addAssign
(
assign
->
loc
->
name
,
assign
->
args
[
0
]
->
name
);
}
...
...
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