Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
C
cs164_lab3_cg
Manage
Activity
Members
Labels
Plan
Issues
0
Issue boards
Milestones
Wiki
Code
Merge requests
0
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
recolic-hust
cs164_lab3_cg
Commits
37ea8f4f
There was an error fetching the commit references. Please try again later.
Verified
Commit
37ea8f4f
authored
6 years ago
by
Recolic Keghart
Browse files
Options
Downloads
Patches
Plain Diff
Fix function calling logic, not done
parent
4135d07a
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/main/java/chocopy/pa3/CodeGenImpl.java
+70
-84
70 additions, 84 deletions
src/main/java/chocopy/pa3/CodeGenImpl.java
with
70 additions
and
84 deletions
src/main/java/chocopy/pa3/CodeGenImpl.java
+
70
−
84
View file @
37ea8f4f
...
...
@@ -71,6 +71,9 @@ public class CodeGenImpl extends CodeGenBase {
// Return value should be in A0
List
<
RiscVBackend
.
Register
>
savedRegs
=
new
ArrayList
<
RiscVBackend
.
Register
>()
{};
// regMgr.registerToSaveAndRestoreInFunc;
// Function return point:
backend
.
emitLocalLabel
(
new
Label
(
"$"
+
funcName
+
"$exitPoint"
),
"Function return point"
);
emitNoop
(
comment
);
backend
.
emitADDI
(
SP
,
FP
,
-(
2
+
savedRegs
.
size
())
*
backend
.
getWordSize
(),
"Revert all local variables on this dying frame."
);
for
(
int
i
=
savedRegs
.
size
();
i
--
>
0
;
)
{
...
...
@@ -87,30 +90,14 @@ public class CodeGenImpl extends CodeGenBase {
backend
.
emitJ
(
new
Label
(
"$"
+
funcName
+
"$saveRegContinue"
),
"go back to execute real function code."
);
}
public
void
emitPushIntVal
(
RiscVBackend
.
Register
tmpReg
,
Integer
val
,
String
comment
)
{
emitNoop
(
comment
);
backend
.
emitLI
(
tmpReg
,
val
,
"INT VAL"
);
emitPush
(
tmpReg
,
null
);
backend
.
emitLA
(
tmpReg
,
intClass
.
getDispatchTableLabel
(),
"OBJECT HEAD - DISPATCH TBL"
);
emitPush
(
tmpReg
,
null
);
backend
.
emitLI
(
tmpReg
,
4
,
"OBJECT HEAD - SIZE = 3+1"
);
emitPush
(
tmpReg
,
null
);
backend
.
emitLI
(
tmpReg
,
1
,
"OBJECT HEAD - TYPE = INT"
);
emitPush
(
tmpReg
,
null
);
backend
.
emitMV
(
tmpReg
,
SP
,
"Return INT address."
);
public
void
emitFunctionReturn
(
String
funcName
,
String
comment
)
{
backend
.
emitJ
(
new
Label
(
"$"
+
funcName
+
"$exitPoint"
),
comment
);
}
public
void
emitPushBoolVal
(
RiscVBackend
.
Register
tmpReg
,
Boolean
val
,
String
comment
)
{
emitNoop
(
comment
);
backend
.
emitLI
(
tmpReg
,
val
?
1
:
0
,
"BOOL VAL"
);
emitPush
(
tmpReg
,
null
);
backend
.
emitLA
(
tmpReg
,
boolClass
.
getDispatchTableLabel
(),
"OBJECT HEAD - DISPATCH TBL"
);
emitPush
(
tmpReg
,
null
);
backend
.
emitLI
(
tmpReg
,
4
,
"OBJECT HEAD - SIZE = 3+1"
);
emitPush
(
tmpReg
,
null
);
backend
.
emitLI
(
tmpReg
,
2
,
"OBJECT HEAD - TYPE = BOOL"
);
emitPush
(
tmpReg
,
null
);
backend
.
emitMV
(
tmpReg
,
SP
,
"Return BOOL address."
);
public
void
emitWrapIntValToIntObject
(
RiscVBackend
.
Register
tmpReg
,
SymbolType
typeIntOrBool
)
{
emitPop
(
tmpReg
,
"INT VAL TO INT OBJ: POP"
);
emitAllocPrototype
(
typeIntOrBool
,
tmpReg
);
emitPush
(
A0
,
"INT VAL TO INT OBJ: PUSH"
);
}
public
void
emitPushStrVal
(
RiscVBackend
.
Register
tmpReg
,
String
val
,
String
comment
)
{
...
...
@@ -143,6 +130,30 @@ public class CodeGenImpl extends CodeGenBase {
emitPush
(
tmpReg
,
null
);
backend
.
emitMV
(
tmpReg
,
SP
,
"Return STR OBJ address."
);
}
private
Void
emitAllocPrototype
(
SymbolType
typ
,
RiscVBackend
.
Register
objReg
)
{
// Convention: if typ is INT_TYPE or BOOL_TYPE then objReg contains the literal value, not a pointer.
// @returns A0
if
(
typ
.
equals
(
SymbolType
.
INT_TYPE
))
{
backend
.
emitLA
(
A0
,
intClass
.
getPrototypeLabel
(),
"Load prototype address"
);
// save our objReg on stack before `alloc`
backend
.
emitADDI
(
SP
,
SP
,
-
4
,
"Decrement stack ptr 1"
);
backend
.
emitSW
(
objReg
,
SP
,
0
,
"Store the literal value"
);
backend
.
emitJAL
(
objectAllocLabel
,
"Allocate int"
);
backend
.
emitLW
(
objReg
,
SP
,
0
,
"Load literal value again"
);
backend
.
emitADDI
(
SP
,
SP
,
4
,
"Increment stack ptr 1"
);
backend
.
emitSW
(
objReg
,
A0
,
3
*
backend
.
getWordSize
(),
"Set __int__ value"
);
}
else
if
(
typ
.
equals
(
SymbolType
.
STR_TYPE
))
{
// objReg already has a ptr in this case. just move to A0.
backend
.
emitMV
(
A0
,
objReg
,
"move string ptr to A0"
);
}
else
if
(
typ
.
equals
(
SymbolType
.
BOOL_TYPE
)){
backend
.
emitLA
(
A0
,
constants
.
getBoolConstant
(
false
),
"Load FALSE bool"
);
backend
.
emitSLLI
(
objReg
,
objReg
,
4
,
"Compute offset to correct object"
);
backend
.
emitADD
(
A0
,
A0
,
objReg
,
"Add offset to curr pointer"
);
}
return
null
;
}
}
...
...
@@ -201,23 +212,15 @@ public class CodeGenImpl extends CodeGenBase {
backend
.
emitGlobalLabel
(
funcInfo
.
getCodeLabel
());
StmtAnalyzer
stmtAnalyzer
=
new
StmtAnalyzer
(
funcInfo
);
// Prologue:
backend
.
emitSW
(
FP
,
SP
,
0
,
"Save old FP"
);
backend
.
emitSW
(
RA
,
SP
,
-
4
,
"Save RA"
);
backend
.
emitADDI
(
SP
,
SP
,
-
8
,
"Increment stack pointer 2 places"
);
backend
.
emitADDI
(
FP
,
SP
,
4
,
"FP is one slot below top of stack"
);
betterBackend
.
emitFunctionBegin
(
funcInfo
.
getFuncName
(),
null
);
// Emit code for function stmts
for
(
Stmt
stmt
:
funcInfo
.
getStatements
())
{
stmt
.
dispatch
(
stmtAnalyzer
);
}
backend
.
emitMV
(
A0
,
ZERO
,
"Returning None implicitly"
);
backend
.
emitLocalLabel
(
stmtAnalyzer
.
epilogue
,
"Epilogue"
);
// FIXME: {... reset fp etc. ...}
backend
.
emitLW
(
RA
,
FP
,
0
,
"Restore RA"
);
backend
.
emitLW
(
FP
,
FP
,
4
,
"Restore old FP"
);
backend
.
emitJR
(
RA
,
"Return to caller"
);
betterBackend
.
emitFunctionEnd
(
funcInfo
.
getFuncName
(),
null
,
null
);
}
/** An analyzer that encapsulates code generation for statments. */
...
...
@@ -265,28 +268,6 @@ public class CodeGenImpl extends CodeGenBase {
private
int
_r_local_label_counter
=
427
;
private
Void
allocPrototype
(
SymbolType
typ
,
RiscVBackend
.
Register
objReg
)
{
// Convention: if typ is INT_TYPE or BOOL_TYPE then objReg contains the literal value, not a pointer.
if
(
typ
.
equals
(
SymbolType
.
INT_TYPE
))
{
backend
.
emitLA
(
A0
,
intClass
.
getPrototypeLabel
(),
"Load prototype address"
);
// save our objReg on stack before `alloc`
backend
.
emitADDI
(
SP
,
SP
,
-
4
,
"Decrement stack ptr 1"
);
backend
.
emitSW
(
objReg
,
SP
,
0
,
"Store the literal value"
);
backend
.
emitJAL
(
objectAllocLabel
,
"Allocate int"
);
backend
.
emitLW
(
objReg
,
SP
,
0
,
"Load literal value again"
);
backend
.
emitADDI
(
SP
,
SP
,
4
,
"Increment stack ptr 1"
);
backend
.
emitSW
(
objReg
,
A0
,
3
*
backend
.
getWordSize
(),
"Set __int__ value"
);
}
else
if
(
typ
.
equals
(
SymbolType
.
STR_TYPE
))
{
// objReg already has a ptr in this case. just move to A0.
backend
.
emitMV
(
A0
,
objReg
,
"move string ptr to A0"
);
}
else
if
(
typ
.
equals
(
SymbolType
.
BOOL_TYPE
)){
backend
.
emitLA
(
A0
,
constants
.
getBoolConstant
(
false
),
"Load FALSE bool"
);
backend
.
emitSLLI
(
objReg
,
objReg
,
4
,
"Compute offset to correct object"
);
backend
.
emitADD
(
A0
,
A0
,
objReg
,
"Add offset to curr pointer"
);
}
return
null
;
}
/** An analyzer for the function described by FUNCINFO0, which is null
* for the top level. */
StmtAnalyzer
(
FuncInfo
funcInfo0
)
{
...
...
@@ -299,14 +280,6 @@ public class CodeGenImpl extends CodeGenBase {
epilogue
=
generateLocalLabel
();
}
// FIXME: Example of statement.
@Override
public
Void
analyze
(
ReturnStmt
stmt
)
{
stmt
.
value
.
dispatch
(
this
);
backend
.
emitLW
(
A0
,
SP
,
0
,
"Load return value into A0"
);
return
null
;
}
@Override
public
Void
analyze
(
ExprStmt
exprStmt
)
{
exprStmt
.
expr
.
dispatch
(
this
);
...
...
@@ -415,30 +388,43 @@ public class CodeGenImpl extends CodeGenBase {
return
null
;
}
@Override
public
Void
analyze
(
ReturnStmt
node
)
{
node
.
value
.
dispatch
(
this
);
betterBackend
.
emitPop
(
A0
,
"ReturnStmt: Get value"
);
betterBackend
.
emitFunctionReturn
(
this
.
funcInfo
.
getFuncName
(),
"ReturnStmt: GO"
);
return
null
;
}
@Override
public
Void
analyze
(
CallExpr
callExpr
)
{
// NOT DONE
if
(
globalSymbols
.
get
(
callExpr
.
function
.
name
)
instanceof
FuncInfo
)
{
FuncInfo
func
=
(
FuncInfo
)
globalSymbols
.
get
(
callExpr
.
function
.
name
);
for
(
Expr
e
:
callExpr
.
args
)
{
backend
.
emitADDI
(
SP
,
SP
,
-
4
,
"Increment stack ptr by 1"
);
e
.
dispatch
(
this
);
}
// Push parameters onto stack
if
(
func
.
getFuncName
().
equals
(
"print"
))
{
backend
.
emitLW
(
T0
,
SP
,
0
,
"Load param for boxing"
);
allocPrototype
(
callExpr
.
args
.
get
(
0
).
getInferredType
(),
T0
);
// after this A0 should contain address of newly allocated object
backend
.
emitSW
(
A0
,
SP
,
0
,
"put boxed argument back on stack"
);
public
Void
analyze
(
CallExpr
node
)
{
SymbolInfo
called
=
sym
.
get
(
node
.
function
.
name
);
if
(
called
instanceof
FuncInfo
)
{
FuncInfo
func
=
(
FuncInfo
)
called
;
// TODO: Push the FUCKING arg0 (outter function frame ptr)
for
(
Expr
expr
:
node
.
args
)
{
expr
.
dispatch
(
this
);
// WARNING: ALL EXPR SHOULD NEVER EDIT STACK POINTER
// THE EXPR PUSH ITS RETURN VAL TO STACK, AS FUNCTION ARG
if
(
func
.
getFuncName
().
equals
(
"print"
))
{
// FUCKING SILLY FUCKING NOOB IDOLT FUNCTION PRINT.
if
(
expr
.
getInferredType
().
equals
(
SymbolType
.
INT_TYPE
)
||
expr
.
getInferredType
().
equals
(
SymbolType
.
BOOL_TYPE
))
betterBackend
.
emitWrapIntValToIntObject
(
T6
,
expr
.
getInferredType
());
}
}
backend
.
emitJAL
(
func
.
getCodeLabel
(),
"Invoke function"
);
// Restore SP
for
(
Expr
e
:
callExpr
.
args
)
{
backend
.
emitADDI
(
SP
,
SP
,
4
,
"Decrement stack ptr by 1"
);
}
betterBackend
.
emitCall
(
func
.
getCodeLabel
(),
null
);
for
(
Object
arg
:
node
.
args
)
betterBackend
.
emitPop
(
null
,
"Pop function arguments."
);
betterBackend
.
emitPush
(
A0
,
"CallExpr: Push function return val"
);
return
null
;
}
else
if
(
called
instanceof
ClassInfo
)
{
// TODO: Fuck the fucking framework.
}
return
null
;
}
...
...
@@ -447,21 +433,21 @@ public class CodeGenImpl extends CodeGenBase {
public
Void
analyze
(
BooleanLiteral
literal
)
{
/* Push boolean literal onto stack, incrementing stack pointer*/
backend
.
emitLI
(
A0
,
(
literal
.
value
==
true
)
?
1
:
0
,
"Load boolean literal into a0"
);
backend
.
emit
SW
(
A0
,
SP
,
0
,
"Push on
stack"
);
b
etterB
ackend
.
emit
Push
(
A0
,
"Push literal onto
stack"
);
return
null
;
}
@Override
public
Void
analyze
(
IntegerLiteral
literal
)
{
backend
.
emitLI
(
A0
,
literal
.
value
,
"Load integer literal into a0"
);
backend
.
emit
SW
(
A0
,
SP
,
0
,
"Push on
stack"
);
b
etterB
ackend
.
emit
Push
(
A0
,
"Push literal onto
stack"
);
return
null
;
}
@Override
public
Void
analyze
(
StringLiteral
literal
)
{
backend
.
emitLA
(
A0
,
constants
.
getStrConstant
(
literal
.
value
),
"Load string addr into a0"
);
backend
.
emit
SW
(
A0
,
SP
,
0
,
"Push on
stack"
);
b
etterB
ackend
.
emit
Push
(
A0
,
"Push literal onto
stack"
);
return
null
;
}
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment