package net.loveruby.cflat.sysdep.x86;
import net.loveruby.cflat.sysdep.CodeGeneratorOptions;
import net.loveruby.cflat.ir.*;
import net.loveruby.cflat.entity.*;
import net.loveruby.cflat.asm.*;
import net.loveruby.cflat.ast.Location;
import net.loveruby.cflat.utils.AsmUtils;
import net.loveruby.cflat.utils.ListUtils;
import net.loveruby.cflat.utils.ErrorHandler;
import java.util.*;
public class CodeGenerator implements net.loveruby.cflat.sysdep.CodeGenerator,
IRVisitor<Void,Void>, ELFConstants {
// #@@range/ctor{
final CodeGeneratorOptions options;
final Type naturalType;
final ErrorHandler errorHandler;
public CodeGenerator(CodeGeneratorOptions options,
Type naturalType, ErrorHandler errorHandler) {
this.options = options;
this.naturalType = naturalType;
this.errorHandler = errorHandler;
}
// #@@}
/** Compiles IR and generates assembly code. */
// #@@range/generate{
public AssemblyCode generate(IR ir) {
locateSymbols(ir);
return generateAssemblyCode(ir);
}
// #@@}
static final String LABEL_SYMBOL_BASE = ".L";
static final String CONST_SYMBOL_BASE = ".LC";
//
// locateSymbols
//
// #@@range/locateSymbols{
private void locateSymbols(IR ir) {
SymbolTable constSymbols = new SymbolTable(CONST_SYMBOL_BASE);
for (ConstantEntry ent : ir.constantTable().entries()) {
locateStringLiteral(ent, constSymbols);
}
for (Variable var : ir.allGlobalVariables()) {
locateGlobalVariable(var);
}
for (Function func : ir.allFunctions()) {
locateFunction(func);
}
}
// #@@}
// #@@range/locateStringLiteral{
private void locateStringLiteral(ConstantEntry ent, SymbolTable syms) {
ent.setSymbol(syms.newSymbol());
if (options.isPositionIndependent()) {
Symbol offset = localGOTSymbol(ent.symbol());
ent.setMemref(mem(offset, GOTBaseReg()));
}
else {
ent.setMemref(mem(ent.symbol()));
ent.setAddress(imm(ent.symbol()));
}
}
// #@@}
// #@@range/locateGlobalVariable{
private void locateGlobalVariable(Entity ent) {
Symbol sym = symbol(ent.symbolString(), ent.isPrivate());
if (options.isPositionIndependent()) {
if (ent.isPrivate() || optimizeGvarAccess(ent)) {
ent.setMemref(mem(localGOTSymbol(sym), GOTBaseReg()));
}
else {
ent.setAddress(mem(globalGOTSymbol(sym), GOTBaseReg()));
}
}
else {
ent.setMemref(mem(sym));
ent.setAddress(imm(sym));
}
}
// #@@}
// #@@range/locateFunction{
private void locateFunction(Function func) {
func.setCallingSymbol(callingSymbol(func));
locateGlobalVariable(func);
}
// #@@}
// #@@range/symbol{
private Symbol symbol(String sym, boolean isPrivate) {
return isPrivate ? privateSymbol(sym) : globalSymbol(sym);
}
// #@@}
// #@@range/globalSymbol{
private Symbol globalSymbol(String sym) {
return new NamedSymbol(sym);
}
// #@@}
// #@@range/privateSymbol{
private Symbol privateSymbol(String sym) {
return new NamedSymbol(sym);
}
// #@@}
// #@@range/callingSymbol{
private Symbol callingSymbol(Function func) {
if (func.isPrivate()) {
return privateSymbol(func.symbolString());
}
else {
Symbol sym = globalSymbol(func.symbolString());
return shouldUsePLT(func) ? PLTSymbol(sym) : sym;
}
}
// #@@}
// #@@range/shouldUsePLT{
private boolean shouldUsePLT(Entity ent) {
return options.isPositionIndependent() && !optimizeGvarAccess(ent);
}
// #@@}
// #@@range/optimizeGvarAccess{
private boolean optimizeGvarAccess(Entity ent) {
return options.isPIERequired() && ent.isDefined();
}
// #@@}
//
// generateAssemblyCode
//
// #@@range/generateAssemblyCode{
private AssemblyCode generateAssemblyCode(IR ir) {
AssemblyCode file = newAssemblyCode();
file._file(ir.fileName());
if (ir.isGlobalVariableDefined()) {
generateDataSection(file, ir.definedGlobalVariables());
}
if (ir.isStringLiteralDefined()) {
generateReadOnlyDataSection(file, ir.constantTable());
}
if (ir.isFunctionDefined()) {
generateTextSection(file, ir.definedFunctions());
}
// #@@range/generateAssemblyCode_last{
if (ir.isCommonSymbolDefined()) {
generateCommonSymbols(file, ir.definedCommonSymbols());
}
if (options.isPositionIndependent()) {
PICThunk(file, GOTBaseReg());
}
return file;
// #@@}
}
// #@@}
// #@@range/newAssemblyCode{
private AssemblyCode newAssemblyCode() {
return new AssemblyCode(
naturalType, STACK_WORD_SIZE,
new SymbolTable(LABEL_SYMBOL_BASE),
options.isVerboseAsm());
}
// #@@}
/** Generates initialized entries */
// #@@range/generateDataSection{
private void generateDataSection(AssemblyCode file,
List<DefinedVariable> gvars) {
file._data();
for (DefinedVariable var : gvars) {
Symbol sym = globalSymbol(var.symbolString());
if (!var.isPrivate()) {
file._globl(sym);
}
file._align(var.alignment());
file._type(sym, "@object");
file._size(sym, var.allocSize());
file.label(sym);
generateImmediate(file, var.type().allocSize(), var.ir());
}
}
// #@@}
/** Generates immediate values for .data section */
// #@@range/generateImmediate{
private void generateImmediate(AssemblyCode file, long size, Expr node) {
if (node instanceof Int) {
Int expr = (Int)node;
switch ((int)size) {
case 1: file._byte(expr.value()); break;
case 2: file._value(expr.value()); break;
case 4: file._long(expr.value()); break;
case 8: file._quad(expr.value()); break;
default:
throw new Error("entry size must be 1,2,4,8");
}
}
else if (node instanceof Str) {
Str expr = (Str)node;
switch ((int)size) {
case 4: file._long(expr.symbol()); break;
case 8: file._quad(expr.symbol()); break;
default:
throw new Error("pointer size must be 4,8");
}
}
else {
throw new Error("unknown literal node type" + node.getClass());
}
}
// #@@}
/** Generates .rodata entries (constant strings) */
// #@@range/generateReadOnlyDataSection{
private void generateReadOnlyDataSection(AssemblyCode file,
ConstantTable constants) {
file._section(".rodata");
for (ConstantEntry ent : constants) {
file.label(ent.symbol());
file._string(ent.value());
}
}
// #@@}
// #@@range/generateTextSection{
private void generateTextSection(AssemblyCode file,
List<DefinedFunction> functions) {
file._text();
for (DefinedFunction func : functions) {
Symbol sym = globalSymbol(func.name());
if (! func.isPrivate()) {
file._globl(sym);
}
file._type(sym, "@function");
file.label(sym);
compileFunctionBody(file, func);
file._size(sym, ".-" + sym.toSource());
}
}
// #@@}
/** Generates BSS entries */
// #@@range/generateCommonSymbols{
没有合适的资源?快使用搜索试试~ 我知道了~
Cb (C flat) compiler. Cb is simplified C..zip
共405个文件
java:191个
cb:174个
hb:15个
需积分: 5 0 下载量 44 浏览量
2023-12-31
10:21:21
上传
评论
收藏 385KB ZIP 举报
温馨提示
Cb (C flat) compiler. Cb is simplified C.
资源推荐
资源详情
资源评论
收起资源包目录
Cb (C flat) compiler. Cb is simplified C..zip (405个子文件)
sizeof_jmpbuf.c 234B
assign.cb 1KB
opassign.cb 1KB
syntax3.cb 1KB
syntax1.cb 1KB
usertype.cb 956B
sizeof-type.cb 800B
sub.cb 775B
funcall5.cb 743B
alloca2.cb 716B
sizeof-expr.cb 633B
ptrmemb.cb 630B
sizeof-struct.cb 593B
addressof.cb 548B
add.cb 541B
struct2.cb 537B
mdarray2.cb 510B
mdarray.cb 506B
ptrarray.cb 502B
inc.cb 461B
scomm.cb 440B
cast.cb 433B
sizeof-union.cb 426B
sgvar.cb 394B
slcomm.cb 386B
block.cb 374B
implicitaddr.cb 355B
struct-semcheck.cb 354B
dec.cb 354B
slvar.cb 346B
comm.cb 341B
union-semcheck.cb 339B
switch.cb 331B
setjmptest.cb 330B
gvar.cb 326B
union.cb 308B
pointer3.cb 297B
funcptr.cb 295B
array.cb 278B
const.cb 276B
ulongops.cb 276B
condexpr.cb 267B
longops.cb 267B
string.cb 263B
lvar2.cb 259B
ucharops2.cb 257B
ucharops.cb 256B
ushortops2.cb 255B
ushortops.cb 254B
ptrdiff.cb 251B
fork.cb 251B
uintops.cb 248B
charops2.cb 248B
charops.cb 247B
shortops2.cb 246B
shortops.cb 245B
intops.cb 239B
integer.cb 230B
eq.cb 229B
neq.cb 229B
initializer.cb 228B
div.cb 222B
array2.cb 212B
varargs.cb 208B
bitor.cb 206B
pointer2.cb 203B
struct.cb 198B
dowhile3.cb 191B
while3.cb 187B
cast2.cb 187B
for1.cb 184B
while-continue.cb 178B
struct-semcheck9.cb 174B
dowhile-continue.cb 174B
logicalnot.cb 168B
rshift.cb 166B
union-semcheck9.cb 166B
stdarg.cb 165B
logicaland.cb 165B
ptrmemb2.cb 164B
lshift.cb 164B
for-continue.cb 164B
logicalor.cb 163B
unaryplus.cb 162B
unaryminus.cb 162B
for-break.cb 161B
param.cb 156B
alloca.cb 155B
vardecl.cb 154B
pointer.cb 151B
dowhile2.cb 149B
struct-semcheck6.cb 148B
struct-semcheck4.cb 147B
union-semcheck6.cb 145B
var-semcheck.cb 144B
bitxor.cb 144B
bitand.cb 144B
empstruct.cb 143B
dowhile-break.cb 142B
while1.cb 141B
共 405 条
- 1
- 2
- 3
- 4
- 5
资源评论
暮苍梧~
- 粉丝: 41
- 资源: 258
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 农村信用社联合社计算机信息系统投产与变更管理办.docx
- 农村信用社联合社计算机信息系统数据管理办法.docx
- 利用SPSS作临床效度分析线上计算网站介绍-医学研究部统计谘.(医学PPT课件).ppt
- 利用Zabbix监控mysqldump定时备份数据库状态.docx
- 利用计算机解决问题的基本过程.doc
- 化工铁路通信工程总结.doc
- 北京大学网络教育软件工程作业.docx
- 医药公司(连锁店)计算机操作规程未新系统的自行按照旧制修改-新系统过制的编号加修模版.doc
- 医药公司(连锁店)计算机系统操作规程模版.doc
- 医药连锁门店计算机系统的操作和管理程序未新系统的自行按照旧制修改-新系统过制的编号加修模版.docx
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功