Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
2
2022fall-Compiler_CMinus
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
李晓奇
2022fall-Compiler_CMinus
Commits
eda3505d
Commit
eda3505d
authored
Jan 27, 2023
by
lxq
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
finish most integer instructions
parent
793fd3dd
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
258 additions
and
41 deletions
+258
-41
include/codegen.hpp
include/codegen.hpp
+46
-13
src/codegen/codegen.cpp
src/codegen/codegen.cpp
+212
-28
No files found.
include/codegen.hpp
View file @
eda3505d
#ifndef CODEGEN_HPP
#ifndef CODEGEN_HPP
#define CODEGEN_HPP
#define CODEGEN_HPP
#include "BasicBlock.h"
#include "Function.h"
#include "Function.h"
#include "Instruction.h"
#include "Instruction.h"
#include "Module.h"
#include "Module.h"
...
@@ -8,8 +9,11 @@
...
@@ -8,8 +9,11 @@
#include "logging.hpp"
#include "logging.hpp"
#include <map>
#include <map>
#include <ostream>
#define STACK_ALIGN(x) (((x / 16) + (x % 16 ? 1 : 0)) * 16)
#define ALIGN(x, align) (((x / align) + (x % align ? 1 : 0)) * align)
// #define STACK_ALIGN(x) (((x / 16) + (x % 16 ? 1 : 0)) * 16)
#define STACK_ALIGN(x) ALIGN(x, 16)
using
std
::
map
;
using
std
::
map
;
using
std
::
string
;
using
std
::
string
;
...
@@ -32,18 +36,23 @@ class CodeGen {
...
@@ -32,18 +36,23 @@ class CodeGen {
void
run
();
void
run
();
private:
private:
void
IR2assem
(
Instruction
&
);
void
IR2assem
(
ReturnInst
*
);
void
IR2assem
(
LoadInst
*
);
void
IR2assem
(
LoadInst
*
);
void
IR2assem
(
StoreInst
*
);
void
IR2assem
(
StoreInst
*
);
void
IR2assem
(
ReturnInst
*
);
void
IR2assem
(
BranchInst
*
)
{}
void
IR2assem
(
Instruction
&
);
void
IR2assem
(
BinaryInst
*
)
{}
void
IR2assem
(
AllocaInst
*
)
{}
void
IR2assem
(
PhiInst
*
)
{}
void
IR2assem
(
CallInst
*
)
{}
void
IR2assem
(
GetElementPtrInst
*
);
void
IR2assem
(
GetElementPtrInst
*
);
void
IR2assem
(
CallInst
*
);
void
IR2assem
(
BranchInst
*
);
// The Instructions below will do nothing
void
IR2assem
(
AllocaInst
*
)
{}
// integration with BranchInst
void
IR2assem
(
CmpInst
*
)
{}
void
IR2assem
(
ZextInst
*
)
{}
void
IR2assem
(
ZextInst
*
)
{}
void
IR2assem
(
BinaryInst
*
);
void
IR2assem
(
PhiInst
*
)
{}
void
IR2assem
(
FCmpInst
*
)
{}
void
IR2assem
(
FpToSiInst
*
)
{}
void
IR2assem
(
FpToSiInst
*
)
{}
void
IR2assem
(
SiToFpInst
*
)
{}
void
IR2assem
(
SiToFpInst
*
)
{}
...
@@ -54,11 +63,16 @@ class CodeGen {
...
@@ -54,11 +63,16 @@ class CodeGen {
// - for global variables and pointers from alloca and GEP, read through
// - for global variables and pointers from alloca and GEP, read through
// address
// address
// only use register a_id and t_
// only use register a_id and t_
void
value2reg
(
Value
*
,
int
id
=
0
);
void
value2reg
(
Value
*
,
int
id
=
0
,
bool
is_float
=
false
);
// load the content in ptr to specified register.
// load the content in ptr to specified register.
// only use register a_id and t_
// only use register a_id and t_
void
ptrContent2reg
(
Value
*
,
int
id
=
0
);
void
ptrContent2reg
(
Value
*
,
int
id
=
0
);
void
compute_arg_info
(
Function
*
);
string
bool2branch
(
Instruction
*
);
string
label_in_assem
(
BasicBlock
*
bb
)
{
return
cur_func
->
get_name
()
+
bb
->
get_name
().
substr
(
5
);
}
int
typeLen
(
Type
*
type
)
{
int
typeLen
(
Type
*
type
)
{
if
(
type
->
is_float_type
())
if
(
type
->
is_float_type
())
return
4
;
return
4
;
...
@@ -73,8 +87,16 @@ class CodeGen {
...
@@ -73,8 +87,16 @@ class CodeGen {
auto
arr_tp
=
static_cast
<
ArrayType
*>
(
type
);
auto
arr_tp
=
static_cast
<
ArrayType
*>
(
type
);
int
n
=
arr_tp
->
get_num_of_elements
();
int
n
=
arr_tp
->
get_num_of_elements
();
return
n
*
typeLen
(
arr_tp
->
get_element_type
());
return
n
*
typeLen
(
arr_tp
->
get_element_type
());
}
else
}
else
{
assert
(
false
&&
"unexpected case while computing type-length"
);
assert
(
false
&&
"unexpected case while computing type-length"
);
}
}
void
back2stack
(
Instruction
*
instr
,
string
reg
=
"$a0"
)
{
// std::cerr << instr->print() << std::endl;
string
suff
=
suffix
(
typeLen
(
instr
->
get_type
()));
string
addr
=
"$fp, -"
+
std
::
to_string
(
off
[
instr
]);
output
.
push_back
(
"st"
+
suff
+
" "
+
reg
+
" "
+
addr
);
}
}
string
suffix
(
int
len
)
{
string
suffix
(
int
len
)
{
...
@@ -91,8 +113,19 @@ class CodeGen {
...
@@ -91,8 +113,19 @@ class CodeGen {
assert
(
false
&&
"no such suffix"
);
assert
(
false
&&
"no such suffix"
);
}
}
std
::
map
<
Value
*
,
unsigned
int
>
off
;
bool
no_stack_alloca
(
Instruction
*
instr
)
{
unsigned
int
N
;
if
(
instr
->
is_void
())
return
true
;
if
(
instr
->
is_cmp
()
or
instr
->
is_zext
())
return
true
;
return
false
;
}
std
::
map
<
Value
*
,
unsigned
int
>
off
;
// to $fp
std
::
map
<
Function
*
,
std
::
map
<
int
,
int
>>
func_arg_off
;
// to $sp
std
::
map
<
Function
*
,
int
>
func_arg_N
;
unsigned
int
stackN
;
Function
*
cur_func
;
Function
*
cur_func
;
...
...
src/codegen/codegen.cpp
View file @
eda3505d
...
@@ -7,6 +7,7 @@
...
@@ -7,6 +7,7 @@
#include "codegen.hpp"
#include "codegen.hpp"
#include "Constant.h"
#include "Constant.h"
#include "Function.h"
#include "GlobalVariable.h"
#include "GlobalVariable.h"
#include "Instruction.h"
#include "Instruction.h"
#include "Type.h"
#include "Type.h"
...
@@ -65,6 +66,10 @@ CodeGen::run() {
...
@@ -65,6 +66,10 @@ CodeGen::run() {
output
.
push_back
(
".comm "
+
globl
.
get_name
()
+
", "
+
output
.
push_back
(
".comm "
+
globl
.
get_name
()
+
", "
+
to_string
(
typeLen
(
type
)));
to_string
(
typeLen
(
type
)));
}
}
// arguments: stack transfer
for
(
auto
&
func
:
m
->
get_functions
())
if
(
not
func
.
is_declaration
())
compute_arg_info
(
&
func
);
// funtions
// funtions
for
(
auto
&
func
:
m
->
get_functions
())
{
for
(
auto
&
func
:
m
->
get_functions
())
{
if
(
not
func
.
is_declaration
())
{
if
(
not
func
.
is_declaration
())
{
...
@@ -77,11 +82,7 @@ CodeGen::run() {
...
@@ -77,11 +82,7 @@ CodeGen::run() {
stackMemAlloc
();
stackMemAlloc
();
for
(
auto
&
bb
:
func
.
get_basic_blocks
())
{
for
(
auto
&
bb
:
func
.
get_basic_blocks
())
{
if
(
&
bb
==
func
.
get_entry_block
())
output
.
push_back
(
label_in_assem
(
&
bb
)
+
":"
);
output
.
push_back
(
func
.
get_name
()
+
"_entry:"
);
else
output
.
push_back
(
func
.
get_name
()
+
"_"
+
bb
.
get_name
().
substr
(
5
)
+
":"
);
for
(
auto
&
instr
:
bb
.
get_instructions
())
{
for
(
auto
&
instr
:
bb
.
get_instructions
())
{
IR2assem
(
instr
);
IR2assem
(
instr
);
}
}
...
@@ -122,8 +123,8 @@ CodeGen::ptrContent2reg(Value *ptr, int id) {
...
@@ -122,8 +123,8 @@ CodeGen::ptrContent2reg(Value *ptr, int id) {
}
}
void
void
CodeGen
::
value2reg
(
Value
*
v
,
int
id
)
{
CodeGen
::
value2reg
(
Value
*
v
,
int
id
,
bool
is_float
)
{
auto
reg_name
=
"$a"
+
to_string
(
id
);
auto
reg_name
=
(
is_float
?
"$f"
:
"$a"
)
+
to_string
(
id
);
if
(
dynamic_cast
<
Constant
*>
(
v
))
{
if
(
dynamic_cast
<
Constant
*>
(
v
))
{
auto
constant
=
static_cast
<
Constant
*>
(
v
);
auto
constant
=
static_cast
<
Constant
*>
(
v
);
if
(
dynamic_cast
<
ConstantInt
*>
(
constant
))
{
if
(
dynamic_cast
<
ConstantInt
*>
(
constant
))
{
...
@@ -142,12 +143,40 @@ CodeGen::value2reg(Value *v, int id) {
...
@@ -142,12 +143,40 @@ CodeGen::value2reg(Value *v, int id) {
}
else
if
(
dynamic_cast
<
AllocaInst
*>
(
v
))
{
}
else
if
(
dynamic_cast
<
AllocaInst
*>
(
v
))
{
// auto alloc_instr = dynamic_cast<AllocaInst *>(v);
// auto alloc_instr = dynamic_cast<AllocaInst *>(v);
output
.
push_back
(
"addi.d "
+
reg_name
+
", $fp, -"
+
to_string
(
off
[
v
]));
output
.
push_back
(
"addi.d "
+
reg_name
+
", $fp, -"
+
to_string
(
off
[
v
]));
}
else
if
(
dynamic_cast
<
Argument
*>
(
v
))
{
auto
args
=
cur_func
->
get_args
();
int
id
=
1
;
for
(
auto
iter
=
args
.
begin
();
id
<=
args
.
size
();
++
iter
,
++
id
)
if
(
*
iter
==
v
)
break
;
output
.
push_back
(
"ld"
+
suffix
(
typeLen
(
v
->
get_type
()))
+
" "
+
reg_name
+
", $fp, "
+
to_string
(
func_arg_off
[
cur_func
][
id
]));
}
else
{
}
else
{
output
.
push_back
(
"ld"
+
suffix
(
typeLen
(
v
->
get_type
()))
+
" "
+
output
.
push_back
(
"ld"
+
suffix
(
typeLen
(
v
->
get_type
()))
+
" "
+
reg_name
+
", $fp, -"
+
to_string
(
off
[
v
]));
reg_name
+
", $fp, -"
+
to_string
(
off
[
v
]));
}
}
}
}
void
CodeGen
::
compute_arg_info
(
Function
*
func
)
{
if
(
func_arg_off
.
find
(
func
)
!=
func_arg_off
.
end
())
return
;
auto
func_tp
=
func
->
get_function_type
();
auto
&
arg_off
=
func_arg_off
[
func
];
int
argN
=
0
,
arg_id
=
func
->
get_num_of_args
();
// reserve space
for
(
auto
iter
=
func_tp
->
param_end
();
iter
!=
func_tp
->
param_begin
();)
{
--
iter
;
auto
tplen
=
typeLen
(
*
iter
);
argN
=
ALIGN
(
argN
,
tplen
)
+
tplen
;
arg_off
[
arg_id
--
]
=
argN
;
}
for
(
arg_id
=
1
;
arg_id
<=
func
->
get_num_of_args
();
++
arg_id
)
arg_off
[
arg_id
]
=
argN
-
arg_off
[
arg_id
];
func_arg_N
[
func
]
=
STACK_ALIGN
(
argN
);
}
void
void
CodeGen
::
stackMemDealloc
()
{
CodeGen
::
stackMemDealloc
()
{
output
.
push_back
(
"# epilog"
);
output
.
push_back
(
"# epilog"
);
...
@@ -155,7 +184,7 @@ CodeGen::stackMemDealloc() {
...
@@ -155,7 +184,7 @@ CodeGen::stackMemDealloc() {
// output.push_back("addi.w $a0, $zero, 0");
// output.push_back("addi.w $a0, $zero, 0");
output
.
push_back
(
cur_func
->
get_name
()
+
"_end:"
);
output
.
push_back
(
cur_func
->
get_name
()
+
"_end:"
);
output
.
push_back
(
"ld.d $ra, $fp, -8"
);
output
.
push_back
(
"ld.d $ra, $fp, -8"
);
output
.
push_back
(
"addi.d $sp, $sp, "
+
to_string
(
N
));
output
.
push_back
(
"addi.d $sp, $sp, "
+
to_string
(
stack
N
));
output
.
push_back
(
"jr $ra"
);
output
.
push_back
(
"jr $ra"
);
}
}
...
@@ -163,28 +192,182 @@ CodeGen::stackMemDealloc() {
...
@@ -163,28 +192,182 @@ CodeGen::stackMemDealloc() {
void
void
CodeGen
::
stackMemAlloc
()
{
CodeGen
::
stackMemAlloc
()
{
// preserved for ra
// preserved for ra
N
=
8
;
stack
N
=
8
;
off
.
clear
();
off
.
clear
();
for
(
auto
&
bb
:
cur_func
->
get_basic_blocks
())
for
(
auto
&
bb
:
cur_func
->
get_basic_blocks
())
for
(
auto
&
instr
:
bb
.
get_instructions
())
{
for
(
auto
&
instr
:
bb
.
get_instructions
())
{
if
(
no
t
instr
.
is_void
())
{
if
(
no
_stack_alloca
(
&
instr
))
if
(
instr
.
is_alloca
())
{
continue
;
auto
alloc_instr
=
static_cast
<
AllocaInst
*>
(
&
instr
)
;
int
tplen
;
N
+=
typeLen
(
alloc_instr
->
get_alloca_type
());
if
(
instr
.
is_alloca
())
{
}
else
{
auto
alloc_instr
=
static_cast
<
AllocaInst
*>
(
&
instr
);
auto
type
=
instr
.
get_type
(
);
tplen
=
typeLen
(
alloc_instr
->
get_alloca_type
()
);
N
+=
typeLen
(
type
);
}
else
{
}
auto
type
=
instr
.
get_type
();
off
[
&
instr
]
=
N
;
tplen
=
typeLen
(
type
)
;
}
}
stackN
=
ALIGN
(
stackN
,
tplen
)
+
tplen
;
off
[
&
instr
]
=
stackN
;
}
}
N
=
STACK_ALIGN
(
N
);
stackN
=
STACK_ALIGN
(
stack
N
);
output
.
push_back
(
"# prolog"
);
output
.
push_back
(
"# prolog"
);
output
.
push_back
(
"addi.d $sp, $sp, -"
+
to_string
(
N
));
output
.
push_back
(
"addi.d $sp, $sp, -"
+
to_string
(
stack
N
));
output
.
push_back
(
"addi.d $fp, $sp, "
+
to_string
(
N
));
output
.
push_back
(
"addi.d $fp, $sp, "
+
to_string
(
stack
N
));
output
.
push_back
(
"st.d $ra, $fp, -8"
);
output
.
push_back
(
"st.d $ra, $fp, -8"
);
}
}
string
CodeGen
::
bool2branch
(
Instruction
*
instr
)
{
assert
(
instr
->
get_type
()
==
instr
->
get_module
()
->
get_int1_type
());
auto
cmp_instr
=
dynamic_cast
<
CmpInst
*>
(
instr
);
assert
(
cmp_instr
);
string
instr_ir
;
bool
reverse
=
false
;
switch
(
cmp_instr
->
get_cmp_op
())
{
case
CmpInst
::
EQ
:
instr_ir
=
"beq"
;
break
;
case
CmpInst
::
NE
:
{
instr_ir
=
"bne"
;
if
(
instr
->
get_operand
(
1
)
==
ConstantInt
::
get
(
0
,
instr
->
get_module
())
and
dynamic_cast
<
Instruction
*>
(
instr
->
get_operand
(
0
))
->
is_zext
())
{
// something like:
// %op0 = icmp slt i32 1, 2 # deepest
// %op1 = zext i1 %op0 to i32
// %op2 = icmp ne i32 %op1, 0
// br i1 %op2, label %label3, label %label5
auto
deepest
=
static_cast
<
Instruction
*>
(
static_cast
<
Instruction
*>
(
instr
->
get_operand
(
0
))
->
get_operand
(
0
));
return
bool2branch
(
deepest
);
}
}
break
;
case
CmpInst
::
GT
:
instr_ir
=
"blt"
;
reverse
=
true
;
break
;
case
CmpInst
::
GE
:
instr_ir
=
"bge"
;
break
;
case
CmpInst
::
LT
:
instr_ir
=
"blt"
;
break
;
case
CmpInst
::
LE
:
instr_ir
=
"bge"
;
reverse
=
true
;
break
;
}
value2reg
(
instr
->
get_operand
(
0
),
0
);
value2reg
(
instr
->
get_operand
(
1
),
1
);
return
instr_ir
+
(
reverse
?
" $a1, $a0 "
:
" $a0, $a1 "
);
}
void
CodeGen
::
IR2assem
(
BranchInst
*
instr
)
{
if
(
instr
->
is_cond_br
())
{
auto
TBB
=
static_cast
<
BasicBlock
*>
(
instr
->
get_operand
(
1
));
auto
FBB
=
static_cast
<
BasicBlock
*>
(
instr
->
get_operand
(
2
));
// value2reg(instr->get_operand(0));
string
instr_ir
=
bool2branch
(
static_cast
<
Instruction
*>
(
instr
->
get_operand
(
0
)));
output
.
push_back
(
instr_ir
+
" "
+
label_in_assem
(
TBB
));
output
.
push_back
(
"b "
+
label_in_assem
(
FBB
));
}
else
{
auto
bb
=
static_cast
<
BasicBlock
*>
(
instr
->
get_operand
(
0
));
output
.
push_back
(
"b "
+
label_in_assem
(
bb
));
}
}
void
CodeGen
::
IR2assem
(
CallInst
*
instr
)
{
auto
func
=
static_cast
<
Function
*>
(
instr
->
get_operand
(
0
));
// stack space allocation
output
.
push_back
(
"addi.d $sp, $sp, -"
+
to_string
(
func_arg_N
[
func
]));
// place the arguments
for
(
int
i
=
1
;
i
<
instr
->
get_num_operand
();
i
++
)
{
auto
arg
=
instr
->
get_operand
(
i
);
auto
tplen
=
typeLen
(
arg
->
get_type
());
string
suff
=
suffix
(
tplen
);
value2reg
(
arg
);
output
.
push_back
(
"st"
+
suff
+
" $a0, $sp, "
+
to_string
(
func_arg_off
[
func
][
i
]));
}
output
.
push_back
(
"bl "
+
func
->
get_name
());
output
.
push_back
(
"addi.d $sp, $sp, "
+
to_string
(
func_arg_N
[
func
]));
output
.
push_back
(
"addi.d $fp, $sp, "
+
to_string
(
stackN
));
if
(
not
instr
->
is_void
())
back2stack
(
instr
);
}
void
CodeGen
::
IR2assem
(
CmpInst
*
instr
)
{
value2reg
(
instr
->
get_operand
(
0
),
0
);
value2reg
(
instr
->
get_operand
(
1
),
1
);
string
instr_ir
;
switch
(
instr
->
get_cmp_op
())
{
case
CmpInst
::
EQ
:
break
;
case
CmpInst
::
NE
:
// output.push_back("xor $a0, $a0, $a1");
break
;
case
CmpInst
::
GT
:
output
.
push_back
(
"slt $a0, $a1, $a0"
);
break
;
case
CmpInst
::
GE
:
break
;
case
CmpInst
::
LT
:
output
.
push_back
(
"slt $a0, $a0, $a1"
);
break
;
case
CmpInst
::
LE
:
break
;
}
output
.
push_back
(
instr_ir
+
" $a0, $a0, $a1"
);
back2stack
(
instr
);
}
void
CodeGen
::
IR2assem
(
BinaryInst
*
instr
)
{
value2reg
(
instr
->
get_operand
(
0
),
0
);
value2reg
(
instr
->
get_operand
(
1
),
1
);
string
suff
=
suffix
(
typeLen
(
instr
->
get_type
()));
string
instr_ir
;
switch
(
instr
->
get_instr_type
())
{
case
Instruction
::
add
:
instr_ir
=
"add"
;
break
;
case
Instruction
::
sub
:
instr_ir
=
"sub"
;
break
;
case
Instruction
::
mul
:
instr_ir
=
"mulw.d.w"
;
suff
=
""
;
break
;
case
Instruction
::
sdiv
:
instr_ir
=
"div"
;
break
;
/* case Instruction::fadd:
* instr_ir = "fadd";
* break;
* case Instruction::fsub:
* instr_ir = "fsub";
* break;
* case Instruction::fmul:
* instr_ir = "fmul";
* break;
* case Instruction::fdiv:
* instr_ir = "fdiv";
* break; */
default:
assert
(
false
&&
"instruction type"
);
}
output
.
push_back
(
instr_ir
+
suff
+
" $a0, $a0, $a1"
);
back2stack
(
instr
);
}
void
void
CodeGen
::
IR2assem
(
GetElementPtrInst
*
instr
)
{
CodeGen
::
IR2assem
(
GetElementPtrInst
*
instr
)
{
value2reg
(
instr
->
get_operand
(
0
),
0
);
value2reg
(
instr
->
get_operand
(
0
),
0
);
...
@@ -203,6 +386,7 @@ CodeGen::IR2assem(GetElementPtrInst *instr) {
...
@@ -203,6 +386,7 @@ CodeGen::IR2assem(GetElementPtrInst *instr) {
output
.
push_back
(
"mul.w $a1, $a1, "
+
to_string
(
size
));
output
.
push_back
(
"mul.w $a1, $a1, "
+
to_string
(
size
));
output
.
push_back
(
"add.d $a0, $a0, $a1"
);
output
.
push_back
(
"add.d $a0, $a0, $a1"
);
}
}
back2stack
(
instr
);
}
}
void
void
...
@@ -210,9 +394,11 @@ CodeGen::IR2assem(LoadInst *instr) {
...
@@ -210,9 +394,11 @@ CodeGen::IR2assem(LoadInst *instr) {
// move the address to a0
// move the address to a0
ptrContent2reg
(
instr
->
get_lval
());
ptrContent2reg
(
instr
->
get_lval
());
string
suff
=
suffix
(
typeLen
(
instr
->
get_load_type
()));
assert
(
instr
->
get_type
()
==
instr
->
get_load_type
());
string
addr
=
"$fp, -"
+
to_string
(
off
[
instr
]);
back2stack
(
instr
);
output
.
push_back
(
"st"
+
suff
+
" $a0, "
+
addr
);
/* string suff = suffix(typeLen(instr->get_load_type()));
* string addr = "$fp, -" + to_string(off[instr]);
* output.push_back("st" + suff + " $a0, " + addr); */
}
}
void
void
...
@@ -244,13 +430,11 @@ CodeGen::IR2assem(Instruction &instr) {
...
@@ -244,13 +430,11 @@ CodeGen::IR2assem(Instruction &instr) {
return
;
return
;
// Standard binary operators
// Standard binary operators
case
Instruction
::
add
:
case
Instruction
::
add
:
break
;
case
Instruction
::
sub
:
case
Instruction
::
sub
:
break
;
case
Instruction
::
mul
:
case
Instruction
::
mul
:
break
;
case
Instruction
::
sdiv
:
case
Instruction
::
sdiv
:
break
;
IR2assem
(
static_cast
<
BinaryInst
*>
(
&
instr
));
return
;
// float binary operators
// float binary operators
case
Instruction
::
fadd
:
case
Instruction
::
fadd
:
break
;
break
;
...
...
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