Initial Commit

This commit is contained in:
pjht 2020-06-21 14:14:57 -05:00
commit 632317095f
79 changed files with 42279 additions and 0 deletions

View File

@ -0,0 +1,16 @@
4 bytes vendor id at 0x0
4 bytes vendor class id at 0x4
4 bytes device id at 0x8
1 byte class at 0xb
1 byte subclass 0xf
1 byte prog if 0x10
1 byte bar enable at 0x11
8 byte BAR0 at 0x12
8 byte BAR1 at 0x1A
8 byte BAR2 at 0x22
8 byte BAR3 at 0x2A
8 byte BAR4 at 0x32
8 byte BAR5 at 0x3A
8 byte BAR6 at 0x42
8 byte BAR7 at 0x4A
173 bytes unused at 0x52 (free for use by devices)

11137
T64.circ Normal file

File diff suppressed because it is too large Load Diff

75
asm.rb Normal file
View File

@ -0,0 +1,75 @@
require_relative "parser.rb"
require_relative "lexer.rb"
if ARGV.length > 0
name = ARGV[0]
else
print "Enter .t64 file name:"
name=gets.chomp!
name+=".t64" unless name.include? ".t64"
end
$infile=File.read(name)
parser=T64.new()
code,labels,linestarts,lineends=parser.parse($infile)
$outfile=File.open(name.gsub(".t64",".hex"),"w")
# $outfile.puts "v2.0 raw"
i=0
outbytes=[]
code.each do |line|
for byte in line
outbytes.push byte
end
len=lineends[i]-linestarts[i]
padding=len-line.length
padding.times do
outbytes.push 0
end
i+=1
end
groups=[]
group=[]
for byte in outbytes
if group.length==8
groups.push group.reverse
group=[]
end
group.push byte
end
groups.push group if group.length>0
p groups
for group in groups
for byte in group
$outfile.print byte.to_s(16).rjust(2,"0")
end
$outfile.puts
end
$outfile.close
$listfile=File.open(name.gsub(".t64",".lst"),"w")
lines=$infile.split("\n")
linestarts.length.times do |i|
start=linestarts[i]
len=lineends[i]-start
linebytes=code[i]
line=lines[i]
$listfile.print (start.to_s(16).rjust(4, "0") + ": ")
if linebytes
linebytes.each do |byte|
$listfile.print (byte.to_s(16).rjust(2, "0") + " ")
end
end
$listfile.print line + "\n"
end
$listfile.puts
$listfile.puts "Symbol table:"
for label,loc in labels
$listfile.puts "#{label}: #{loc.to_s(16).rjust(8,"0")}"
end
$listfile.close

View File

@ -0,0 +1,220 @@
$labelno=0
$free_regs=[]
$mapping={"__irasmtemp__"=>"r13"}
$types={}
BP="r14"
SP="r15"
def prefix_for(var)
if $types[var]
case $types[var]
when 8
return "B"
when 16
return "W"
when 32
return "DW"
end
else
return ""
end
end
def gen_label()
label="label#{$labelno}"
$labelno+=1
return label
end
def push(reg)
return "ARI r15,r15,8,SUB,0\nST #{reg},(#{SP})\n"
end
def pop(reg)
return "LD #{reg},(#{SP})\nARI r15,r15,8,ADD,0\n"
end
def get_mapping(var)
if $mapping[var]
return $mapping[var]
else
return var
end
end
def load_in_reg(*vars); end
def in_reg(var)
if $mapping[var]
return true
else
return false
end
end
def extern_var(var)
if $mapping[var]
return false
else
return true
end
end
def array_arg_maker(base,off)
if in_reg(off) and in_reg(base)
return "#{get_mapping(off)}(#{get_mapping(base)})"
elsif in_reg(off) and !in_reg(base)
return "#{get_mapping(off)}(#{base})"
elsif !in_reg(off) and in_reg(base)
return "#{off}(#{get_mapping(base)})"
else
return "#{off}(#{base})"
end
end
def gen_expr(expr,dest)
load_in_reg(dest)
case expr[:type]
when :add
load_in_reg(expr[:v1],expr[:v2])
return "AR#{prefix_for(dest)} #{get_mapping(dest)},#{get_mapping(expr[:v1])},#{get_mapping(expr[:v2])},ADD,0\n"
when :sub
load_in_reg(expr[:v1],expr[:v2])
return "AR#{prefix_for(dest)} #{get_mapping(dest)},#{get_mapping(expr[:v1])},#{get_mapping(expr[:v2])},SUB,0\n"
when :bitor
load_in_reg(expr[:v1],expr[:v2])
return "AR#{prefix_for(dest)} #{get_mapping(dest)},#{get_mapping(expr[:v1])},#{get_mapping(expr[:v2])},OR,0\n"
when :inv
load_in_reg(expr[:val])
return "AR#{prefix_for(dest)} #{get_mapping(dest)},#{get_mapping(expr[:val])},r0,NOT,0\n"
when :deref
if in_reg(expr[:addr])
return "LD#{prefix_for(dest)} #{get_mapping(dest)},(#{get_mapping(expr[:addr])})\n"
else
return "LD#{prefix_for(dest)} #{get_mapping(dest)},(#{expr[:addr]})\n"
end
when :array
return "LD#{prefix_for(dest)} #{get_mapping(dest)},#{array_arg_maker(expr[:off],expr[:base])}\n"
when :num
return "LD#{prefix_for(dest)} #{get_mapping(dest)},#{expr[:val]}\n"
when :var
if in_reg(expr[:var])
return "AR#{prefix_for(dest)} #{get_mapping(dest)},#{get_mapping(expr[:var])},r0,ADD,1\n"
else
return "LD#{prefix_for(dest)} #{get_mapping(dest)}, #{expr[:var]}\n"
end
end
end
def gen_stmt(stmt)
case stmt[:type]
when :set
if extern_var(stmt[:var])
code=gen_expr(stmt[:expr],"__irasmtemp__")
return code+="ST#{prefix_for("__irasmtemp__")} #{$mapping["__irasmtemp__"]},(#{get_mapping(stmt[:var])})\n"
else
return gen_expr(stmt[:expr],stmt[:var])
end
when :arrayset
code=gen_expr(stmt[:expr],"__irasmtemp__")
return code+="ST#{prefix_for("__irasmtemp__")} #{$mapping["__irasmtemp__"]},#{array_arg_maker(stmt[:off],stmt[:base])}\n"
when :type
if $free_regs.length==0
#TODO: Implement register spilling
puts "Registers full, exiting"
exit 1
else
reg=$free_regs.shift
$mapping[stmt[:var]]="r#{reg}"
$types[stmt[:var]]=stmt[:typ]
end
return ""
when :asmline
return stmt[:line]+"\n"
when :while
case stmt[:cond]
when :gt0
label=gen_label()
code="#{label}:\n"
for stmt in stmt[:code]
line=gen_stmt(stmt)
code+=line
end
code+="JNZ (#{label})\n"
return code
end
when :for
if stmt[:init]
code=gen_stmt(stmt[:init])
else
code=""
end
condlabel=gen_label()
endlabel=gen_label()
code+="#{condlabel}:\n"
case stmt[:cond]
when :gt0
code+="JZ #{endlabel}\n"
end
for stmt in stmt[:code]
line=gen_stmt(stmt)
code+=line
end
if stmt[:post]
code+=gen_stmt(stmt[:init])
end
code+="#{endlabel}:\n"
return code
when :call
code=""
for var,reg in $mapping
next if var=="__irasmtemp__"
code+=push(reg)
end
code+="JST r13,(r0)\n"
for var,reg in $mapping
next if var=="__irasmtemp__"
code+=pop(reg)
end
return code
when :callpoint
code=""
for var,reg in $mapping
next if var=="__irasmtemp__"
code+=push(reg)
end
code+="LD r0,(#{stmt[:func]})\n"
code+="JST r13,(#{stmt[:func]})\n"
for var,reg in $mapping
next if var=="__irasmtemp__"
code+=pop(reg)
end
return code
end
end
def generate(ast)
$labelno=0
$free_regs=[]
$mapping={"__irasmtemp__"=>"r13"}
$types={}
13.times do |i|
$free_regs.push i
end
for func in ast
code+="#{func[:name]}:\n"
code+=push(BP)
code+="AR #{BP},#{SP},r0,ADD,1\n"
stmts=func[:code]
for stmt in stmts
line=gen_stmt(stmt)
if line==nil
puts "Cannot generate code for #{stmt}. Exiting."
exit 1
end
code+=line
end
code+="AR #{SP},#{BP},ADD,1\n"
code+=pop(BP)
end
return code
end

28
c_compiler/compiler.rb Normal file
View File

@ -0,0 +1,28 @@
require_relative "frontend/frontend.rb"
require_relative "middleend/middleend.rb"
# require_relative "backend/backend.rb"
require "YAML"
if ARGV.length > 0
name = ARGV[0]
else
print "Enter .c file name:"
name=gets.chomp!
name+=".c" unless name.include? ".c"
end
code=File.read(name)
ir=genir(code)
ir=optimize(ir)
for func in ir
puts "#{func[:name]}() {"
for stmt in func[:code]
puts " #{stmt}"
end
puts "}"
end
# asm=generate(ir)
#
# outfile=File.open(name.gsub(".c",".asm"),"w")
# outfile.print asm
# outfile.close

93
c_compiler/file Normal file
View File

@ -0,0 +1,93 @@
main() {
[nil, "rom_size.0", "type_extern", 64]
[nil, nil, "stmt_done"]
[nil, "ram_size.0", "type_extern", 64]
[nil, nil, "stmt_done"]
[nil, "pci_base.0", "type_extern", 64]
[nil, nil, "stmt_done"]
[nil, "rom_sz_val.0", "type", 64]
["exprc_temp.0", "rom_size.0", "var"]
["rom_sz_val.1", "rom_size.0", "*"]
[nil, nil, "expr_done"]
[nil, nil, "stmt_done"]
[nil, "ram_sz_val.0", "type", 64]
["exprc_temp.1", "ram_size.0", "var"]
["ram_sz_val.1", "ram_size.0", "*"]
[nil, nil, "expr_done"]
[nil, nil, "stmt_done"]
[nil, "hdd_start.0", "type", 64]
["hdd_start.1", "rom_sz_val.1", "var"]
["exprc_temp.2", "ram_sz_val.1", "var"]
["hdd_start.2", "rom_sz_val.1", "+", "ram_sz_val.1"]
[nil, nil, "expr_done"]
[nil, nil, "stmt_done"]
[nil, "len_mask.0", "type", 64]
["exprc_temp1.0", "pci_base.0", "var"]
["exprc_temp2.0", 18, "num"]
["len_mask.1", "pci_base.0", "[]", 18]
[nil, nil, "expr_done"]
[nil, nil, "stmt_done"]
["hdd_start.3", "hdd_start.2", "var"]
["exprc_temp.3", "len_mask.1", "var"]
["exprc_temp.4", "len_mask.1", "~"]
["hdd_start.4", "hdd_start.2", "|", "exprc_temp.4"]
["exprc_temp.5", 1, "num"]
["hdd_start.5", "hdd_start.4", "+", 1]
[nil, nil, "expr_done"]
[nil, nil, "stmt_done"]
["c_temp1.0", "pci_base.0", "var"]
[nil, nil, "expr_done"]
["c_temp2.0", 18, "num"]
[nil, nil, "expr_done"]
["c_temp3.0", "hdd_start.5", "var"]
[nil, nil, "expr_done"]
["pci_base.0", 18, "[]=", "hdd_start.5"]
[nil, nil, "stmt_done"]
["c_temp1.1", "pci_base.0", "var"]
[nil, nil, "expr_done"]
["c_temp2.1", 17, "num"]
[nil, nil, "expr_done"]
["c_temp3.1", 1, "num"]
[nil, nil, "expr_done"]
["pci_base.0", 17, "[]=", 1]
[nil, nil, "stmt_done"]
[nil, nil, "start_scope"]
[nil, "idx.0", "type", 16]
["idx.1", 512, "num"]
[nil, nil, "expr_done"]
[nil, nil, "stmt_done"]
[nil, "label0.", ":"]
["c_temp1.2", 512, "var"]
["exprc_temp.6", 0, "num"]
["c_temp1.3", 512, ">", 0]
[nil, nil, "expr_done"]
[nil, "c_temp1.3", "ifnot", "label1."]
["idx.2", 512, "var"]
["exprc_temp.7", 1, "num"]
["idx.3", 512, "-", 1]
[nil, nil, "expr_done"]
[nil, nil, "stmt_done"]
[nil, "byte_tmp.0", "type", 8]
["exprc_temp1.1", "hdd_start.5", "var"]
["exprc_temp2.1", "idx.3", "var"]
["byte_tmp.1", "hdd_start.5", "[]", "idx.3"]
[nil, nil, "expr_done"]
[nil, nil, "stmt_done"]
["c_temp1.4", "rom_sz_val.1", "var"]
[nil, nil, "expr_done"]
["c_temp2.2", "idx.3", "var"]
[nil, nil, "expr_done"]
["c_temp3.2", "byte_tmp.1", "var"]
[nil, nil, "expr_done"]
["rom_sz_val.1", "idx.3", "[]=", "byte_tmp.1"]
[nil, nil, "stmt_done"]
[nil, "label0.", "goto"]
[nil, "label1.", ":"]
[nil, nil, "end_scope"]
[nil, nil, "stmt_done"]
["exprc_temp.8", "rom_sz_val.1", "var"]
["c_temp1.5", "rom_sz_val.1", "*"]
[nil, nil, "expr_done"]
[nil, "c_temp1.5", "*()"]
[nil, nil, "stmt_done"]
}

55
c_compiler/frontend/c.rex Normal file
View File

@ -0,0 +1,55 @@
class C
macro
SPACE [\ ]+
rule
\/\/.+ {}
(\w+:)?[A-Z]+\s.+; { [:ASM,text]}
(\w+:).*; { [:ASM,text]}
0x[0-9a-f]+ { [:NUM, text.to_i(16)] }
\d+ { [:NUM, text.to_i] }
{SPACE} { }
\n { }
; { [:SEMICOLON,text] }
\( { [:LPAREN,text] }
\) { [:RPAREN,text] }
, { [:COMMA,text] }
: { [:COLON,text]}
= { [:EQUAL,text]}
\* { [:ASTERISK,text]}
\[ { [:LBRACK,text]}
\] { [:RBRACK,text]}
\{ { [:LCURL,text]}
\} { [:RCURL,text]}
\+ { [:PLUS,text]}
- { [:MINUS,text]}
\| { [:PIPE,text]}
~ { [:TILDE,text]}
> { [:GT,text]}
char { [:TYPE,text]}
short { [:TYPE,text]}
int { [:TYPE,text]}
long { [:TYPE,text]}
while { [:WHILE,text]}
for { [:FOR,text]}
extern { [:EXTERN,text]}
\w+ { [:IDENT,text]}
. { [:UNK,text]}
inner
def tokenize(code)
scan_setup(code)
tokens = []
while token = next_token
tokens << token
end
tokens
end
def make_bytes(val)
bytes=[]
8.times do |i|
mask=0xFF << i*8
byte=(val&mask) >> i*8
bytes.push byte
end
return bytes
end
end

91
c_compiler/frontend/c.y Normal file
View File

@ -0,0 +1,91 @@
class C
rule
program: func program {result=[val[0],val[1]].flatten} | func {result=[val[0]]}
func: type IDENT LPAREN RPAREN block {result={:name=>val[1],:rtype=>val[0],:code=>val[4]}}
block: LCURL lines RCURL {result=val[1]}
lines: line lines {result=[val[0],val[1]].flatten} | line {result=[val[0]]}
line: stmt SEMICOLON {result=val[0]}
| stmtnosemi {result=val[0]}
| ASM {result={:type=>:asmline,:line=>val[0].chop}}
stmt: IDENT EQUAL expr {result={:type=>:set,:var=>val[0],:expr=>val[2],:line=>@lineno}}
| postfixexp EQUAL expr {result={:type=>:arrayset,:getexpr=>val[0],:expr=>val[2]}}
| type IDENT {result={:type=>:vardec,:var=>val[1],:typ=>val[0]}}
| type IDENT EQUAL expr {result={:type=>:vardec,:var=>val[1],:typ=>val[0],:init=>val[3]}}
| EXTERN type IDENT {result={:type=>:vardec,:var=>val[2],:typ=>val[1],:extern=>true}}
| expr LPAREN RPAREN {result={:type=>:call,:addr=>val[0]}}
optstmtsemi: stmt SEMICOLON {result=val[0]}
| SEMICOLON {result=nil}
optexprsemi: expr SEMICOLON {result=val[0]}
| SEMICOLON {result=nil}
optstmtparen: stmt RPAREN {result=val[0]}
| RPAREN {result=nil}
stmtnosemi: WHILE LPAREN expr RPAREN block {result={:type=>:while,:cond=>val[2],:code=>val[4]}}
| FOR LPAREN optstmtsemi optexprsemi optstmtparen block {result={:type=>:for,:init=>val[2],:cond=>val[3],:post=>val[4],:code=>val[5]}}
factor: NUM {result={:type=>:num,:val=>val[0]}}
| IDENT {result={:type=>:var,:var=>val[0],:line=>@lineno}}
| LPAREN expr RPAREN {result=val[1]}
postfixexp: factor
| postfixexp LBRACK expr RBRACK {result={:type=>:array,:off=>val[2],:base=>val[0]}}
unaryexp: postfixexp
| ASTERISK castexp {result={:type=>:deref,:addr=>val[1]}}
| TILDE castexp {result={:type=>:inv,:val=>val[1]}}
castexp: unaryexp
| LPAREN type RPAREN castexp {result={:type=>:cast,:typ=>val[1],:expr=>val[3]}}
addexp: castexp
| addexp PLUS castexp {result={:type=>:add,:v1=>val[0],:v2=>val[2]}}
| addexp MINUS castexp {result={:type=>:sub,:v1=>val[0],:v2=>val[2]}}
cmpexp: addexp
| cmpexp GT addexp {result={:type=>:gt,:v1=>val[0],:v2=>val[2]}}
bitor: cmpexp
| bitor PIPE cmpexp {result={:type=>:bitor,:v1=>val[0],:v2=>val[2]}}
expr: bitor
type: TYPE {result={:type_type=>:scalar,:type=>val[0]}}
| TYPE ASTERISK {result={:type_type=>:pointer,:type=>val[0]}}
end
---- inner
def initialize()
@yydebug=true
super
end
def parse(input)
scan_str(input)
end
def get_label(label)
if @labels[label]
return make_bytes(@labels[label])
else
return [label]+[0]*7
end
end
def make_bytes(val)
bytes=[]
8.times do |i|
mask=0xFF << i*8
byte=(val&mask) >> i*8
bytes.push byte
end
return bytes
end
def defed_label(label)
for index in @bytes.each_index.select {|index| @bytes[index]==label}
@bytes[index,8]=make_bytes(@labels[label])
end
end

View File

@ -0,0 +1,256 @@
require_relative "parser.rb"
require_relative "lexer.rb"
$vars={}
$type_to_len={"char"=>8,"short"=>16,"int"=>32,"long"=>64}
$immvals={}
$labelno=0
$errors=false
def gen_label()
label="label#{$labelno}"
$labelno+=1
return label
end
def val_for(var)
# puts "val for #{var}"
# puts $immvals
# puts $vars
if $immvals[var]
val=$immvals[var]
$immvals[var]=nil
else
if !(var.match /c_temp/) and $vars[var]==nil
puts "error: use of undeclared variable '#{var}'"
$errors=true
end
val=var
end
return val
end
def is_num(val)
return val.is_a? Numeric || (val.match /^\d+$/)!=nil
end
def binop(dest,var1,op,var2)
code=[]
code+=gen_expr(var1,dest,true)
code+=gen_expr(var2,"exprc_temp",true)
var1=val_for(dest)
var2=val_for("exprc_temp")
# if is_num(var1) and is_num(var2)
# $immvals[dest]=eval("#{var1}#{op}#{var2}")
# else
code.push [dest,var1,op,var2]
# end
return code
end
def gen_expr(expr,dest,in_recurse=false)
# puts "GEN EXPR #{expr}"
code=[]
case expr[:type]
when :bitor
code+=binop(dest,expr[:v1],"|",expr[:v2])
when :gt
code+=binop(dest,expr[:v1],">",expr[:v2])
when :add
code+=binop(dest,expr[:v1],"+",expr[:v2])
when :sub
code+=binop(dest,expr[:v1],"-",expr[:v2])
when :num
code.push [dest,expr[:val],"num"]
# $immvals[dest]=expr[:val]
when :var
if $vars[expr[:var]]==nil and (expr[:var].match /c_temp/)==nil
puts "error: use of undeclared variable '#{expr[:var]}' at line #{expr[:line]}"
$errors=true
end
code.push [dest,expr[:var],"var"]
# $immvals[dest]=expr[:var]
when :deref
code+=gen_expr(expr[:addr],"exprc_temp",true)
# if $immvals["exprc_temp"]
# if $immvals["exprc_temp"].is_a? String
# puts $vars
# puts $vars[$immvals["exprc_temp"]]
# if $vars[$immvals["exprc_temp"]][:type_type]!="pointer"
# puts "Warning! Dereferencing #{$vars[$immvals["exprc_temp"]][:type]} #{$immvals["exprc_temp"]}"
# end
# end
# $immvals[dest]="*#{val_for("exprc_temp")}"
# else
code.push [dest,"exprc_temp","*"]
# end
when :inv
code+=gen_expr(expr[:val],"exprc_temp",true)
code.push [dest,"exprc_temp","~"]
when :array
code+=gen_expr(expr[:base],"exprc_temp1",true)
code+=gen_expr(expr[:off],"exprc_temp2",true)
code.push [dest,"exprc_temp1","[]","exprc_temp2"]
when :cast
code=gen_expr(expr[:expr],dest,true)
len=$type_to_len[expr[:typ][:type]]
# if $immvals[dest]
# if $immvals[dest].match /^\d+$/
# case len
# when 8
# code.push "#{dest}=#{$immvals[dest]}&0xFF;\n"
# when 16
# code.push "#{dest}=#{$immvals[dest]}&0xFFFF;\n"
# when 32
# code.push "#{dest}=#{$immvals[dest]}&0xFFFFFFFF;\n"
# end
# else
# currlen=$type_to_len[$vars[$immvals[dest]][:type]]
# case len
# when 8
# code.push "#{dest}=#{dest}&0xFF;\n" if currlen>8
# when 16
# code.push "#{dest}=#{dest}&0xFFFF;\n" if currlen>16
# when 32
# code.push "#{dest}=#{dest}&0xFFFFFFFF;\n" if currlen>32
# end
# end
# $immvals[dest]=nil
# else
case expr[:typ][:type_type]
when :scalar
if $vars[dest]==nil
currlen=64
else
currlen=$type_to_len[$vars[dest][:type]]
end
case len
when 8
code.push [dest,dest,"&","0xFF"] if currlen>8
when 16
code.push [dest,dest,"&","0xFFFF"] if currlen>16
when 32
code.push [dest,dest,"&","0xFFFFFFFF"] if currlen>32
end
# end
end
end
if !in_recurse
code.push [nil,nil,"expr_done"]
$used_exp_temps=false
end
# puts "DONE EXPR"
return code
end
def gen_stmt(stmt)
# puts "GEN STMT #{stmt}"
code=[]
case stmt[:type]
when :vardec
$vars[stmt[:var]]=stmt[:typ]
type_stmt=stmt[:extern] ? "type_extern" : "type"
case stmt[:typ][:type_type]
when :scalar
code.push [nil,stmt[:var],type_stmt,$type_to_len[stmt[:typ][:type]]]
when :pointer
code.push [nil,stmt[:var],type_stmt,64]
end
if stmt[:init]
code+=gen_expr(stmt[:init],stmt[:var])
# if $immvals[stmt[:var]]
# code.push "#{stmt[:var]}=#{val_for(stmt[:var])};\n"
# $immvals[stmt[:var]]=nil
# end
elsif !stmt[:extern]
code.push [stmt[:var],stmt[:var],"^",stmt[:var]]
end
when :set
if $vars[stmt[:var]]==nil and !stmt[:var].match /c_temp/
puts "error: use of undeclared variable '#{stmt[:var]}' at line #{stmt[:line]}"
$errors=true
end
code+=gen_expr(stmt[:expr],stmt[:var])
# if $immvals[stmt[:var]]
# code.push "#{stmt[:var]}=#{val_for(stmt[:var])};\n"
# $immvals[stmt[:var]]=nil
# end
when :arrayset
code+=gen_expr(stmt[:getexpr][:base],"c_temp1")
code+=gen_expr(stmt[:getexpr][:off],"c_temp2")
code+=gen_expr(stmt[:expr],"c_temp3")
code.push ["c_temp1","c_temp2","[]=","c_temp3"]
when :call
code+=gen_expr(stmt[:addr],"c_temp1")
code.push [nil,"c_temp1","*()"]
when :while
cond_label=gen_label()
end_label=gen_label()
code.push [nil,nil,"start_scope"]
code.push [nil,cond_label,":"]
if stmt[:cond]
code+=gen_expr(stmt[:cond],"c_temp1")
code.push [nil,c_temp1,"ifnot",end_label]
end
for stmt in stmt[:code]
line=gen_stmt(stmt)
if line==[]
puts "Cannot generate code for #{stmt}. Skipping."
else
code.push line
end
end
code.push [nil,cond_label,"goto"]
code.push [nil,nil,"end_scope"]
when :for
cond_label=gen_label()
end_label=gen_label()
code.push [nil,nil,"start_scope"]
if stmt[:init]
code+=gen_stmt(stmt[:init])
end
code.push [nil,cond_label,":"]
if stmt[:cond]
code+=gen_expr(stmt[:cond],"c_temp1")
code.push [nil,"c_temp1","ifnot",end_label]
end
for stmt in stmt[:code]
line=gen_stmt(stmt)
if line==nil
puts "Cannot generate code for #{stmt}. Skipping."
else
code+=line
end
end
if stmt[:post]
code+=gen_stmt(stmt[:post])
end
code.push [nil,cond_label,"goto"]
code.push [nil,end_label,":"]
code.push [nil,nil,"end_scope"]
end
code.push [nil,nil,"stmt_done"]
$used_c_temps=false
# puts "DONE STMT"
return code
end
def genir(code)
parser=C.new()
ast=parser.parse(code)
irast=[]
for func in ast
code=[]
stmts=func[:code]
for stmt in stmts
line=gen_stmt(stmt)
if line==nil
puts "Cannot generate code for #{stmt}. Skipping."
else
code+=line
end
end
irast.push({:name=>func[:name],:code=>code})
end
return irast
end

View File

@ -0,0 +1,184 @@
#--
# DO NOT MODIFY!!!!
# This file is automatically generated by rex 1.0.5
# from lexical definition file "c.rex".
#++
require 'racc/parser'
class C < Racc::Parser
require 'strscan'
class ScanError < StandardError ; end
attr_reader :lineno
attr_reader :filename
attr_accessor :state
def scan_setup(str)
@ss = StringScanner.new(str)
@lineno = 1
@state = nil
end
def action
yield
end
def scan_str(str)
scan_setup(str)
do_parse
end
alias :scan :scan_str
def load_file( filename )
@filename = filename
open(filename, "r") do |f|
scan_setup(f.read)
end
end
def scan_file( filename )
load_file(filename)
do_parse
end
def next_token
return if @ss.eos?
# skips empty actions
until token = _next_token or @ss.eos?; end
token
end
def _next_token
text = @ss.peek(1)
@lineno += 1 if text == "\n"
token = case @state
when nil
case
when (text = @ss.scan(/\/\/.+/))
action {}
when (text = @ss.scan(/(\w+:)?[A-Z]+\s.+;/))
action { [:ASM,text]}
when (text = @ss.scan(/(\w+:).*;/))
action { [:ASM,text]}
when (text = @ss.scan(/0x[0-9a-f]+/))
action { [:NUM, text.to_i(16)] }
when (text = @ss.scan(/\d+/))
action { [:NUM, text.to_i] }
when (text = @ss.scan(/[ ]+/))
action { }
when (text = @ss.scan(/\n/))
action { }
when (text = @ss.scan(/;/))
action { [:SEMICOLON,text] }
when (text = @ss.scan(/\(/))
action { [:LPAREN,text] }
when (text = @ss.scan(/\)/))
action { [:RPAREN,text] }
when (text = @ss.scan(/,/))
action { [:COMMA,text] }
when (text = @ss.scan(/:/))
action { [:COLON,text]}
when (text = @ss.scan(/=/))
action { [:EQUAL,text]}
when (text = @ss.scan(/\*/))
action { [:ASTERISK,text]}
when (text = @ss.scan(/\[/))
action { [:LBRACK,text]}
when (text = @ss.scan(/\]/))
action { [:RBRACK,text]}
when (text = @ss.scan(/\{/))
action { [:LCURL,text]}
when (text = @ss.scan(/\}/))
action { [:RCURL,text]}
when (text = @ss.scan(/\+/))
action { [:PLUS,text]}
when (text = @ss.scan(/-/))
action { [:MINUS,text]}
when (text = @ss.scan(/\|/))
action { [:PIPE,text]}
when (text = @ss.scan(/~/))
action { [:TILDE,text]}
when (text = @ss.scan(/>/))
action { [:GT,text]}
when (text = @ss.scan(/char/))
action { [:TYPE,text]}
when (text = @ss.scan(/short/))
action { [:TYPE,text]}
when (text = @ss.scan(/int/))
action { [:TYPE,text]}
when (text = @ss.scan(/long/))
action { [:TYPE,text]}
when (text = @ss.scan(/while/))
action { [:WHILE,text]}
when (text = @ss.scan(/for/))
action { [:FOR,text]}
when (text = @ss.scan(/extern/))
action { [:EXTERN,text]}
when (text = @ss.scan(/\w+/))
action { [:IDENT,text]}
when (text = @ss.scan(/./))
action { [:UNK,text]}
else
text = @ss.string[@ss.pos .. -1]
raise ScanError, "can not match: '" + text + "'"
end # if
else
raise ScanError, "undefined state: '" + state.to_s + "'"
end # case state
token
end # def _next_token
def tokenize(code)
scan_setup(code)
tokens = []
while token = next_token
tokens << token
end
tokens
end
def make_bytes(val)
bytes=[]
8.times do |i|
mask=0xFF << i*8
byte=(val&mask) >> i*8
bytes.push byte
end
return bytes
end
end # class

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,542 @@
#
# DO NOT MODIFY!!!!
# This file is automatically generated by Racc 1.4.14
# from Racc grammer file "".
#
require 'racc/parser.rb'
class C < Racc::Parser
module_eval(<<'...end c.y/module_eval...', 'c.y', 64)
def initialize()
@yydebug=true
super
end
def parse(input)
scan_str(input)
end
def get_label(label)
if @labels[label]
return make_bytes(@labels[label])
else
return [label]+[0]*7
end
end
def make_bytes(val)
bytes=[]
8.times do |i|
mask=0xFF << i*8
byte=(val&mask) >> i*8
bytes.push byte
end
return bytes
end
def defed_label(label)
for index in @bytes.each_index.select {|index| @bytes[index]==label}
@bytes[index,8]=make_bytes(@labels[label])
end
end
...end c.y/module_eval...
##### State transition tables begin ###
racc_action_table = [
19, 27, 19, 27, 84, 65, 62, 40, 22, 67,
22, 26, 41, 26, 29, 30, 29, 30, 47, 27,
4, 41, 4, 53, 54, 53, 54, 68, 73, 26,
75, 76, 29, 30, 19, 27, 55, 13, 4, 82,
18, 86, 22, 24, 25, 26, 4, 13, 29, 30,
19, 27, 47, 27, 4, 5, 18, 4, 22, 24,
25, 26, 7, 26, 29, 30, 29, 30, 47, 27,
4, 8, 9, 47, 27, 47, 27, 10, 11, 26,
47, 27, 29, 30, 26, 78, 26, 29, 30, 29,
30, 26, 47, 27, 29, 30, 13, 47, 27, 47,
27, 36, 38, 26, 47, 27, 29, 30, 26, 39,
26, 29, 30, 29, 30, 26, 47, 27, 29, 30,
42, 47, 27, 47, 27, 4, 44, 26, 47, 27,
29, 30, 26, 45, 26, 29, 30, 29, 30, 26,
46, 55, 29, 30, 56, 60, 61 ]
racc_action_check = [
46, 46, 79, 79, 79, 46, 44, 20, 46, 48,
79, 46, 20, 79, 46, 46, 79, 79, 27, 27,
46, 49, 79, 33, 33, 71, 71, 50, 59, 27,
63, 64, 27, 27, 13, 13, 72, 75, 27, 77,
13, 83, 13, 13, 13, 13, 0, 85, 13, 13,
15, 15, 56, 56, 13, 1, 15, 2, 15, 15,
15, 15, 3, 56, 15, 15, 56, 56, 60, 60,
15, 4, 5, 39, 39, 40, 40, 7, 10, 60,
66, 66, 60, 60, 39, 66, 40, 39, 39, 40,
40, 66, 68, 68, 66, 66, 11, 41, 41, 45,
45, 14, 16, 68, 30, 30, 68, 68, 41, 19,
45, 41, 41, 45, 45, 30, 53, 53, 30, 30,
21, 54, 54, 55, 55, 22, 23, 53, 29, 29,
53, 53, 54, 24, 55, 54, 54, 55, 55, 29,
25, 34, 29, 29, 35, 42, 43 ]
racc_action_pointer = [
24, 55, 35, 60, 55, 72, nil, 74, nil, nil,
74, 91, nil, 32, 95, 48, 95, nil, nil, 100,
-2, 118, 103, 123, 130, 137, nil, 16, nil, 126,
102, nil, nil, 5, 121, 123, nil, nil, nil, 71,
73, 95, 136, 144, 2, 97, -2, nil, 5, 7,
23, nil, nil, 114, 119, 121, 50, nil, nil, 13,
66, nil, nil, 26, 24, nil, 78, nil, 90, nil,
nil, 7, 16, nil, nil, 32, nil, 32, nil, 0,
nil, nil, nil, 37, nil, 42, nil, nil ]
racc_action_default = [
-44, -44, -2, -44, -42, -44, -1, -44, -43, 88,
-44, -44, -3, -44, -44, -6, -44, -8, -9, -25,
-29, -44, -44, -44, -44, -44, -24, -44, -27, -44,
-44, -32, -34, -37, -39, -41, -4, -5, -7, -44,
-44, -44, -12, -44, -44, -44, -44, -25, -44, -29,
-44, -30, -31, -44, -44, -44, -44, -10, -11, -44,
-44, -14, -15, -44, -44, -17, -44, -26, -44, -35,
-36, -38, -40, -28, -13, -44, -16, -44, -19, -44,
-33, -22, -18, -44, -21, -44, -20, -23 ]
racc_goto_table = [
12, 20, 48, 20, 51, 52, 64, 79, 1, 3,
6, 3, 85, 66, 57, 58, 59, 14, 71, 37,
63, 72, nil, nil, nil, nil, nil, nil, 69, 70,
nil, 43, nil, nil, 20, 74, 50, nil, nil, 83,
nil, 77, nil, 80, nil, nil, nil, nil, nil, nil,
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
nil, nil, nil, nil, 81, nil, nil, 20, nil, nil,
nil, nil, nil, nil, 87 ]
racc_goto_check = [
4, 10, 9, 10, 16, 16, 7, 12, 1, 3,
1, 3, 13, 11, 9, 9, 9, 5, 17, 5,
9, 18, nil, nil, nil, nil, nil, nil, 16, 16,
nil, 3, nil, nil, 10, 9, 3, nil, nil, 7,
nil, 9, nil, 16, nil, nil, nil, nil, nil, nil,
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
nil, nil, nil, nil, 4, nil, nil, 10, nil, nil,
nil, nil, nil, nil, 4 ]
racc_goto_pointer = [
nil, 8, nil, 9, -11, 4, nil, -40, nil, -25,
-12, -33, -59, -67, nil, nil, -25, -37, -35, nil ]
racc_goto_default = [
nil, nil, 2, 21, nil, nil, 15, 16, 17, 23,
49, nil, nil, nil, 28, 31, 32, 33, 34, 35 ]
racc_reduce_table = [
0, 0, :racc_error,
2, 24, :_reduce_1,
1, 24, :_reduce_2,
5, 25, :_reduce_3,
3, 27, :_reduce_4,
2, 28, :_reduce_5,
1, 28, :_reduce_6,
2, 29, :_reduce_7,
1, 29, :_reduce_8,
1, 29, :_reduce_9,
3, 30, :_reduce_10,
3, 30, :_reduce_11,
2, 30, :_reduce_12,
4, 30, :_reduce_13,
3, 30, :_reduce_14,
3, 30, :_reduce_15,
2, 34, :_reduce_16,
1, 34, :_reduce_17,
2, 35, :_reduce_18,
1, 35, :_reduce_19,
2, 36, :_reduce_20,
1, 36, :_reduce_21,
5, 31, :_reduce_22,
6, 31, :_reduce_23,
1, 37, :_reduce_24,
1, 37, :_reduce_25,
3, 37, :_reduce_26,
1, 33, :_reduce_none,
4, 33, :_reduce_28,
1, 38, :_reduce_none,
2, 38, :_reduce_30,
2, 38, :_reduce_31,
1, 39, :_reduce_none,
4, 39, :_reduce_33,
1, 40, :_reduce_none,
3, 40, :_reduce_35,
3, 40, :_reduce_36,
1, 41, :_reduce_none,
3, 41, :_reduce_38,
1, 42, :_reduce_none,
3, 42, :_reduce_40,
1, 32, :_reduce_none,
1, 26, :_reduce_42,
2, 26, :_reduce_43 ]
racc_reduce_n = 44
racc_shift_n = 88
racc_token_table = {
false => 0,
:error => 1,
:IDENT => 2,
:LPAREN => 3,
:RPAREN => 4,
:LCURL => 5,
:RCURL => 6,
:SEMICOLON => 7,
:ASM => 8,
:EQUAL => 9,
:EXTERN => 10,
:WHILE => 11,
:FOR => 12,
:NUM => 13,
:LBRACK => 14,
:RBRACK => 15,
:ASTERISK => 16,
:TILDE => 17,
:PLUS => 18,
:MINUS => 19,
:GT => 20,
:PIPE => 21,
:TYPE => 22 }
racc_nt_base = 23
racc_use_result_var = true
Racc_arg = [
racc_action_table,
racc_action_check,
racc_action_default,
racc_action_pointer,
racc_goto_table,
racc_goto_check,
racc_goto_default,
racc_goto_pointer,
racc_nt_base,
racc_reduce_table,
racc_token_table,
racc_shift_n,
racc_reduce_n,
racc_use_result_var ]
Racc_token_to_s_table = [
"$end",
"error",
"IDENT",
"LPAREN",
"RPAREN",
"LCURL",
"RCURL",
"SEMICOLON",
"ASM",
"EQUAL",
"EXTERN",
"WHILE",
"FOR",
"NUM",
"LBRACK",
"RBRACK",
"ASTERISK",
"TILDE",
"PLUS",
"MINUS",
"GT",
"PIPE",
"TYPE",
"$start",
"program",
"func",
"type",
"block",
"lines",
"line",
"stmt",
"stmtnosemi",
"expr",
"postfixexp",
"optstmtsemi",
"optexprsemi",
"optstmtparen",
"factor",
"unaryexp",
"castexp",
"addexp",
"cmpexp",
"bitor" ]
Racc_debug_parser = false
##### State transition tables end #####
# reduce 0 omitted
module_eval(<<'.,.,', 'c.y', 2)
def _reduce_1(val, _values, result)
result=[val[0],val[1]].flatten
result
end
.,.,
module_eval(<<'.,.,', 'c.y', 2)
def _reduce_2(val, _values, result)
result=[val[0]]
result
end
.,.,
module_eval(<<'.,.,', 'c.y', 4)
def _reduce_3(val, _values, result)
result={:name=>val[1],:rtype=>val[0],:code=>val[4]}
result
end
.,.,
module_eval(<<'.,.,', 'c.y', 6)
def _reduce_4(val, _values, result)
result=val[1]
result
end
.,.,
module_eval(<<'.,.,', 'c.y', 8)
def _reduce_5(val, _values, result)
result=[val[0],val[1]].flatten
result
end
.,.,
module_eval(<<'.,.,', 'c.y', 8)
def _reduce_6(val, _values, result)
result=[val[0]]
result
end
.,.,
module_eval(<<'.,.,', 'c.y', 10)
def _reduce_7(val, _values, result)
result=val[0]
result
end
.,.,
module_eval(<<'.,.,', 'c.y', 11)
def _reduce_8(val, _values, result)
result=val[0]
result
end
.,.,
module_eval(<<'.,.,', 'c.y', 12)
def _reduce_9(val, _values, result)
result={:type=>:asmline,:line=>val[0].chop}
result
end
.,.,
module_eval(<<'.,.,', 'c.y', 14)
def _reduce_10(val, _values, result)
result={:type=>:set,:var=>val[0],:expr=>val[2],:line=>@lineno}
result
end
.,.,
module_eval(<<'.,.,', 'c.y', 15)
def _reduce_11(val, _values, result)
result={:type=>:arrayset,:getexpr=>val[0],:expr=>val[2]}
result
end
.,.,
module_eval(<<'.,.,', 'c.y', 16)
def _reduce_12(val, _values, result)
result={:type=>:vardec,:var=>val[1],:typ=>val[0]}
result
end
.,.,
module_eval(<<'.,.,', 'c.y', 17)
def _reduce_13(val, _values, result)
result={:type=>:vardec,:var=>val[1],:typ=>val[0],:init=>val[3]}
result
end
.,.,
module_eval(<<'.,.,', 'c.y', 18)
def _reduce_14(val, _values, result)
result={:type=>:vardec,:var=>val[2],:typ=>val[1],:extern=>true}
result
end
.,.,
module_eval(<<'.,.,', 'c.y', 19)
def _reduce_15(val, _values, result)
result={:type=>:call,:addr=>val[0]}
result
end
.,.,
module_eval(<<'.,.,', 'c.y', 21)
def _reduce_16(val, _values, result)
result=val[0]
result
end
.,.,
module_eval(<<'.,.,', 'c.y', 22)
def _reduce_17(val, _values, result)
result=nil
result
end
.,.,
module_eval(<<'.,.,', 'c.y', 24)
def _reduce_18(val, _values, result)
result=val[0]
result
end
.,.,
module_eval(<<'.,.,', 'c.y', 25)
def _reduce_19(val, _values, result)
result=nil
result
end
.,.,
module_eval(<<'.,.,', 'c.y', 27)
def _reduce_20(val, _values, result)
result=val[0]
result
end
.,.,
module_eval(<<'.,.,', 'c.y', 28)
def _reduce_21(val, _values, result)
result=nil
result
end
.,.,
module_eval(<<'.,.,', 'c.y', 30)
def _reduce_22(val, _values, result)
result={:type=>:while,:cond=>val[2],:code=>val[4]}
result
end
.,.,
module_eval(<<'.,.,', 'c.y', 31)
def _reduce_23(val, _values, result)
result={:type=>:for,:init=>val[2],:cond=>val[3],:post=>val[4],:code=>val[5]}
result
end
.,.,
module_eval(<<'.,.,', 'c.y', 33)
def _reduce_24(val, _values, result)
result={:type=>:num,:val=>val[0]}
result
end
.,.,
module_eval(<<'.,.,', 'c.y', 34)
def _reduce_25(val, _values, result)
result={:type=>:var,:var=>val[0],:line=>@lineno}
result
end
.,.,
module_eval(<<'.,.,', 'c.y', 35)
def _reduce_26(val, _values, result)
result=val[1]
result
end
.,.,
# reduce 27 omitted
module_eval(<<'.,.,', 'c.y', 38)
def _reduce_28(val, _values, result)
result={:type=>:array,:off=>val[2],:base=>val[0]}
result
end
.,.,
# reduce 29 omitted
module_eval(<<'.,.,', 'c.y', 41)
def _reduce_30(val, _values, result)
result={:type=>:deref,:addr=>val[1]}
result
end
.,.,
module_eval(<<'.,.,', 'c.y', 42)
def _reduce_31(val, _values, result)
result={:type=>:inv,:val=>val[1]}
result
end
.,.,
# reduce 32 omitted
module_eval(<<'.,.,', 'c.y', 45)
def _reduce_33(val, _values, result)
result={:type=>:cast,:typ=>val[1],:expr=>val[3]}
result
end
.,.,
# reduce 34 omitted
module_eval(<<'.,.,', 'c.y', 48)
def _reduce_35(val, _values, result)
result={:type=>:add,:v1=>val[0],:v2=>val[2]}
result
end
.,.,
module_eval(<<'.,.,', 'c.y', 49)
def _reduce_36(val, _values, result)
result={:type=>:sub,:v1=>val[0],:v2=>val[2]}
result
end
.,.,
# reduce 37 omitted
module_eval(<<'.,.,', 'c.y', 52)
def _reduce_38(val, _values, result)
result={:type=>:gt,:v1=>val[0],:v2=>val[2]}
result
end
.,.,
# reduce 39 omitted
module_eval(<<'.,.,', 'c.y', 55)
def _reduce_40(val, _values, result)
result={:type=>:bitor,:v1=>val[0],:v2=>val[2]}
result
end
.,.,
# reduce 41 omitted
module_eval(<<'.,.,', 'c.y', 58)
def _reduce_42(val, _values, result)
result={:type_type=>:scalar,:type=>val[0]}
result
end
.,.,
module_eval(<<'.,.,', 'c.y', 59)
def _reduce_43(val, _values, result)
result={:type_type=>:pointer,:type=>val[0]}
result
end
.,.,
def _reduce_none(val, _values, result)
val[0]
end
end # class C

55
c_compiler/ir.rex Normal file
View File

@ -0,0 +1,55 @@
class IR
macro
SPACE [\ ]+
rule
\/\/.+ {}
(\w+:)?[A-Z]+\s.+; { [:ASM,text]}
(\w+:).*; { [:ASM,text]}
0x[0-9a-f]+ { [:NUM, text.to_i(16)] }
\d+ { [:NUM, text.to_i] }
{SPACE} { }
\n { @line+=1 }
; { [:SEMICOLON,text] }
\( { [:LPAREN,text] }
\) { [:RPAREN,text] }
, { [:COMMA,text] }
: { [:COLON,text]}
= { [:EQUAL,text]}
\* { [:ASTERISK,text]}
\[ { [:LBRACK,text]}
\] { [:RBRACK,text]}
\{ { [:LCURL,text]}
\} { [:RCURL,text]}
\+ { [:PLUS,text]}
- { [:MINUS,text]}
\| { [:PIPE,text]}
~ { [:TILDE,text]}
>0 { [:GT0,text]}
type { [:TYPE,text]}
while { [:WHILE,text]}
for { [:FOR,text]}
\w+ { [:IDENT,text]}
. { [:UNK,text]}
inner
def initialize()
super
@line=1
end
def tokenize(code)
scan_setup(code)
tokens = []
while token = next_token
tokens << token
end
tokens
end
def make_bytes(val)
bytes=[]
8.times do |i|
mask=0xFF << i*8
byte=(val&mask) >> i*8
bytes.push byte
end
return bytes
end
end

51
c_compiler/ir.y Normal file
View File

@ -0,0 +1,51 @@
class IR
rule
program: func program {result=[val[0],val[1]].flatten} | func {result=[val[0]]}
func: IDENT LPAREN RPAREN block {result={:name=>val[0],:code=>val[3]}}
block: LCURL lines RCURL {result=val[1]}
lines: line lines {result=[val[0],val[1]].flatten} | line {result=[val[0]]}
line: stmt SEMICOLON {result=val[0]}
| ASM {result={:type=>:asmline,:line=>val[0].chop}}
stmt: IDENT EQUAL expr {result={:type=>:set,:var=>val[0],:expr=>val[2]}}
| IDENT LBRACK IDENT RBRACK EQUAL expr {result={:type=>:arrayset,:off=>val[2],:base=>val[0],:expr=>val[5]}}
| IDENT LBRACK NUM RBRACK EQUAL expr {result={:type=>:arrayset,:off=>val[2],:base=>val[0],:expr=>val[5]}}
| TYPE IDENT NUM {result={:type=>:type,:var=>val[1],:typ=>val[2]}}
| IDENT LPAREN RPAREN {result={:type=>:call,:func=>val[0]}}
| ASTERISK IDENT LPAREN RPAREN {result={:type=>:callpoint,:func=>val[1]}}
expr: ASTERISK IDENT {result={:type=>:deref,:addr=>val[1]}}
| IDENT LBRACK IDENT RBRACK {result={:type=>:array,:off=>val[2],:base=>val[0]}}
| IDENT LBRACK NUM RBRACK {result={:type=>:array,:off=>val[2],:base=>val[0]}}
| NUM {result={:type=>:num,:val=>val[0]}}
| IDENT {result={:type=>:var,:var=>val[0]}}
| IDENT PLUS IDENT {result={:type=>:add,:v1=>val[0],:v2=>val[2]}}
| IDENT MINUS IDENT {result={:type=>:sub,:v1=>val[0],:v2=>val[2]}}
| IDENT PIPE IDENT {result={:type=>:bitor,:v1=>val[0],:v2=>val[3]}}
| TILDE IDENT {result={:type=>:inv,:val=>val[1]}}
end
---- inner
def parse(input)
scan_str(input)
end
def get_label(label)
if @labels[label]
return make_bytes(@labels[label])
else
return [label]+[0]*7
end
end
def make_bytes(val)
bytes=[]
8.times do |i|
mask=0xFF << i*8
byte=(val&mask) >> i*8
bytes.push byte
end
return bytes
end
def defed_label(label)
for index in @bytes.each_index.select {|index| @bytes[index]==label}
@bytes[index,8]=make_bytes(@labels[label])
end
end

View File

@ -0,0 +1,28 @@
$immvals={}
def constprop_stmt(stmt)
if $immvals[stmt[0]] && stmt[2]=="[]="
stmt[0]=$immvals[stmt[0]]
end
if $immvals[stmt[1]]
stmt[1]=$immvals[stmt[1]]
end
if $immvals[stmt[3]]
stmt[3]=$immvals[stmt[3]]
end
if stmt[2]=="num" || stmt[2]=="var"
$immvals[stmt[0]]=stmt[1]
end
return stmt
end
def constprop(ast)
for func in ast
newcode=[]
for stmt in func[:code]
newcode.push constprop_stmt(stmt)
end
func[:code]=newcode
end
return ast
end

View File

@ -0,0 +1,41 @@
$used=[]
$set=[]
def deadcode_getinfo(stmt)
# p stmt
if stmt[2]=="[]="
$used.push stmt[0] if !$used.include? stmt[0] and stmt[0]!=nil
else
$set.push stmt[0] if !$set.include? stmt[0] and stmt[0]!=nil
end
$used.push stmt[1] if !$used.include? stmt[1] and stmt[1]!=nil
$used.push stmt[3] if !$used.include? stmt[3] and stmt[1]!=nil
end
def deadcode_stmt(stmt,unused)
stmt=nil if unused.include? stmt[0] and stmt[2]!="[]="
return stmt
end
def deadcode(ast)
for func in ast
for stmt in func[:code]
deadcode_getinfo(stmt)
end
unused=[1]
while unused!=[]
$set=[]
$used=[]
for stmt in func[:code]
deadcode_getinfo(stmt)
end
unused=$set-$used
newcode=[]
for stmt in func[:code]
newcode.push deadcode_stmt(stmt,unused)
end
func[:code]=newcode.compact
end
end
return ast
end

View File

@ -0,0 +1,10 @@
require_relative "constprop.rb"
require_relative "deadcode.rb"
require_relative "ssa.rb"
def optimize(ast)
ast=tossa(ast)
ast=constprop(ast)
# ast=deadcode(ast)
# ast=fromssa(ast)
return ast
end

View File

@ -0,0 +1,69 @@
$vers={}
def isvar(var)
return !(var.is_a? Numeric)
end
def tossa_stmt(stmt)
if stmt[2]=="type" || stmt[2]=="type_extern"
$vers[stmt[1]]=0
stmt[1]="#{stmt[1]}.0"
return stmt
end
if stmt[1] and isvar(stmt[1])
stmt[1]="#{stmt[1]}.#{$vers[stmt[1]]}"
end
if stmt[3] and isvar(stmt[3])
stmt[3]="#{stmt[3]}.#{$vers[stmt[3]]}"
end
if stmt[2]=="[]="
if stmt[0] and isvar(stmt[0])
stmt[0]="#{stmt[0]}.#{$vers[stmt[0]]}"
end
else
if stmt[0] and isvar(stmt[0])
$vers[stmt[0]]=-1 if $vers[stmt[0]]==nil
$vers[stmt[0]]+=1
stmt[0]="#{stmt[0]}.#{$vers[stmt[0]]}"
end
end
return stmt
end
def fromssa_stmt(stmt)
if stmt[0] and isvar(stmt[0])
stmt[0].match(/(.+)\.\d+/)
stmt[0]=$1
end
if stmt[1] and isvar(stmt[1])
stmt[1].match(/(.+)\.\d+/)
stmt[1]=$1
end
if stmt[3] and isvar(stmt[3])
stmt[3].match(/(.+)\.\d+/)
stmt[3]=$1
end
return stmt
end
def tossa(ast)
for func in ast
newcode=[]
for stmt in func[:code]
newcode.push tossa_stmt(stmt)
end
func[:code]=newcode
end
return ast
end
def fromssa(ast)
for func in ast
newcode=[]
for stmt in func[:code]
newcode.push fromssa_stmt(stmt)
end
func[:code]=newcode
end
return ast
end

22
c_compiler/rom.c Normal file
View File

@ -0,0 +1,22 @@
// long* rom_size=(long*)0x1000;
// long* ram_size=(long*)0x1000000;
// long* pci_base=(long*)0xFFFFFFFFFF000000;
int main() {
extern long* rom_size;
extern long* ram_size;
extern long* pci_base;
long rom_sz_val=*rom_size;
long ram_sz_val=*ram_size;
long* hdd_start=(long*)(rom_sz_val+ram_sz_val);
long len_mask=pci_base[0x12];
hdd_start=(long*)((long)hdd_start|~len_mask)+1;
pci_base[0x12]=(long)hdd_start; //set BAR0 of hdd to first free address
pci_base[0x11]=1; //enable hdd BAR0
for (short idx=512;idx>0;) {
idx=idx-1;
char byte_tmp=hdd_start[idx]; //set r3 to byte from HDD
((char*)rom_sz_val)[idx]=byte_tmp; //store HDD byte to RAM
}
*rom_sz_val();
}

261
c_compiler/rom.ir Normal file
View File

@ -0,0 +1,261 @@
---
- :name: main
:code:
- -
- rom_size
- type_extern
- 64
- -
- ram_size
- type_extern
- 64
- -
- pci_base
- type_extern
- 64
- -
- rom_sz_val
- extern
- 64
- - exprc_temp
- rom_size
- "="
- - rom_sz_val
- exprc_temp
- "*"
- -
-
- expr_temp_done
- -
- ram_sz_val
- extern
- 64
- - exprc_temp
- ram_size
- "="
- - ram_sz_val
- exprc_temp
- "*"
- -
-
- expr_temp_done
- -
- hdd_start
- extern
- 64
- - - hdd_start
- rom_sz_val
- "="
- - - exprc_temp
- ram_sz_val
- "="
- - hdd_start
- hdd_start
- "+"
- exprc_temp
- -
-
- expr_temp_done
- -
- len_mask
- extern
- 64
- - exprc_temp1
- pci_base
- "="
- - exprc_temp2
- 18
-
- - len_mask
- exprc_temp1
- "[]"
- exprc_temp2
- -
-
- expr_temp_done
- - - - hdd_start
- hdd_start
- "="
- - - exprc_temp
- len_mask
- "="
- - exprc_temp
- exprc_temp
- "~"
- - hdd_start
- hdd_start
- "|"
- exprc_temp
- - - exprc_temp
- 1
-
- - hdd_start
- hdd_start
- "+"
- exprc_temp
- -
-
- expr_temp_done
- - c_temp1
- pci_base
- "="
- - c_temp2
- 18
-
- - c_temp3
- hdd_start
- "="
- - c_temp1
- c_temp2
- "[]="
- c_temp3
- -
-
- temp_done
- - c_temp1
- pci_base
- "="
- - c_temp2
- 17
-
- - c_temp3
- 1
-
- - c_temp1
- c_temp2
- "[]="
- c_temp3
- -
-
- temp_done
- -
- testing
- extern
- 32
- - - - testing
- 1
-
- - - exprc_temp
- 3
-
- - testing
- testing
- "+"
- exprc_temp
- - - exprc_temp
- 2
-
- - testing
- testing
- "-"
- exprc_temp
- -
-
- expr_temp_done
- -
-
- start_scope
- -
- idx
- extern
- 16
- - idx
- 512
-
- -
- label0
- ":"
- - - c_temp1
- idx
- "="
- - - exprc_temp
- 0
-
- - c_temp1
- c_temp1
- ">"
- exprc_temp
- -
-
- expr_temp_done
- -
- c_temp1
- ifnot
- label1
- -
- byte_tmp
- extern
- 8
- - byte_tmp
- byte_tmp
- "^"
- byte_tmp
- -
-
- temp_done
- - - idx
- idx
- "="
- - - exprc_temp
- 1
-
- - idx
- idx
- "-"
- exprc_temp
- -
-
- expr_temp_done
- - exprc_temp1
- hdd_start
- "="
- - exprc_temp2
- idx
- "="
- - byte_tmp
- exprc_temp1
- "[]"
- exprc_temp2
- -
-
- expr_temp_done
- - c_temp1
- rom_sz_val
- "="
- - c_temp2
- idx
- "="
- - c_temp3
- byte_tmp
- "="
- - c_temp1
- c_temp2
- "[]="
- c_temp3
- -
-
- temp_done
- -
- label0
- goto
- -
- label1
- ":"
- -
-
- end_scope
- - exprc_temp
- rom_sz_val
- "="
- - c_temp1
- exprc_temp
- "*"
- -
-
- expr_temp_done
- -
- c_temp1
- "*()"
- -
-
- temp_done

57
c_compiler/rom.t64 Normal file
View File

@ -0,0 +1,57 @@
main:
ARI r15,r15,8,SUB
ST r14,(r15)
ARI r14,r15,0,ADD
LD r0,(rom_size)
LD r1,(ram_size)
AR r2,r0,r1,ADD
LD r3,pci_base(18)
AR r3,r3,r0,NOT
AR r2,r2,,OR
LDB r4,1
AR r2,r2,r4,ADD
ARI r13,r2,0,ADD
ST r13,pci_base(18)
ARI r13,r4,0,ADD
ST r13,pci_base(17)
LDW r5,512
label0:
JZ label1
ARW r5,r5,r4,SUB
LDB r6,r2(r5)
ARI r13,r6,0,ADD
ST r13,r0(r5)
label1:
ARI r15,r15,8,SUB
ST r0,(r15)
ARI r15,r15,8,SUB
ST r1,(r15)
ARI r15,r15,8,SUB
ST r2,(r15)
ARI r15,r15,8,SUB
ST r3,(r15)
ARI r15,r15,8,SUB
ST r4,(r15)
ARI r15,r15,8,SUB
ST r5,(r15)
ARI r15,r15,8,SUB
ST r6,(r15)
LD r0,(rom_sz_val)
JST r13,(rom_sz_val)
LD r0,(r15)
ARI r15,r15,8,ADD
LD r1,(r15)
ARI r15,r15,8,ADD
LD r2,(r15)
ARI r15,r15,8,ADD
LD r3,(r15)
ARI r15,r15,8,ADD
LD r4,(r15)
ARI r15,r15,8,ADD
LD r5,(r15)
ARI r15,r15,8,ADD
LD r6,(r15)
ARI r15,r15,8,ADD
ARI r15,r14,0,ADD
LD r14,(r15)
ARI r15,r15,8,ADD

259
lexer.rb Normal file
View File

@ -0,0 +1,259 @@
#--
# DO NOT MODIFY!!!!
# This file is automatically generated by rex 1.0.5
# from lexical definition file "t64.rex".
#++
require 'racc/parser'
class T64 < Racc::Parser
require 'strscan'
class ScanError < StandardError ; end
attr_reader :lineno
attr_reader :filename
attr_accessor :state
def scan_setup(str)
@ss = StringScanner.new(str)
@lineno = 1
@state = nil
end
def action
yield
end
def scan_str(str)
scan_setup(str)
do_parse
end
alias :scan :scan_str
def load_file( filename )
@filename = filename
open(filename, "r") do |f|
scan_setup(f.read)
end
end
def scan_file( filename )
load_file(filename)
do_parse
end
def next_token
return if @ss.eos?
# skips empty actions
until token = _next_token or @ss.eos?; end
token
end
def _next_token
text = @ss.peek(1)
@lineno += 1 if text == "\n"
token = case @state
when nil
case
when (text = @ss.scan(/reta/))
action { [:REG,15] }
when (text = @ss.scan(/r\d+/))
action { [:REG,text.to_i]}
when (text = @ss.scan(/0x[0-9a-f]+/))
action { [:NUM, make_bytes(text.to_i(16))] }
when (text = @ss.scan(/\d+/))
action { [:NUM, make_bytes(text.to_i)] }
when (text = @ss.scan(/\n/))
action { [:NEWLINE,"\n"]}
when (text = @ss.scan(/[ ]+/))
action { }
when (text = @ss.scan(/\(/))
action { [:LPAREN,"("] }
when (text = @ss.scan(/\)/))
action { [:RPAREN,")"] }
when (text = @ss.scan(/,/))
action { [:COMMA,","] }
when (text = @ss.scan(/\#.+/))
action {}
when (text = @ss.scan(/:/))
action { [:COLON,text]}
when (text = @ss.scan(/LDB/))
action { [:LDB,text] }
when (text = @ss.scan(/LDW/))
action { [:LDW,text] }
when (text = @ss.scan(/LDDW/))
action { [:LDDW,text] }
when (text = @ss.scan(/LD/))
action { [:LD,text] }
when (text = @ss.scan(/STB/))
action { [:STB,text] }
when (text = @ss.scan(/STW/))
action { [:STW,text] }
when (text = @ss.scan(/STDW/))
action { [:STDW,text] }
when (text = @ss.scan(/ST/))
action { [:ST,text] }
when (text = @ss.scan(/ARIB/))
action { [:ARIB,text] }
when (text = @ss.scan(/ARIW/))
action { [:ARIW,text] }
when (text = @ss.scan(/ARIDW/))
action { [:ARIDW,text] }
when (text = @ss.scan(/ARI/))
action { [:ARI,text] }
when (text = @ss.scan(/ARB/))
action { [:ARB,text] }
when (text = @ss.scan(/ARW/))
action { [:ARW,text] }
when (text = @ss.scan(/ARDW/))
action { [:ARDW,text] }
when (text = @ss.scan(/AR/))
action { [:AR,text] }
when (text = @ss.scan(/JMP/))
action { [:JMP,text] }
when (text = @ss.scan(/JC/))
action { [:JC,text] }
when (text = @ss.scan(/JNC/))
action { [:JNC,text] }
when (text = @ss.scan(/JZ/))
action { [:JZ,text] }
when (text = @ss.scan(/JNZ/))
action { [:JNZ,text] }
when (text = @ss.scan(/JST/))
action { [:JST,text] }
when (text = @ss.scan(/db/))
action { [:DB,text] }
when (text = @ss.scan(/dw/))
action { [:DW,text] }
when (text = @ss.scan(/ddw/))
action { [:DDW,text] }
when (text = @ss.scan(/dqw/))
action { [:DQW,text] }
when (text = @ss.scan(/org/))
action { [:ORG,text] }
when (text = @ss.scan(/NOT/))
action { [:AROP,text] }
when (text = @ss.scan(/AND/))
action { [:AROP,text] }
when (text = @ss.scan(/OR/))
action { [:AROP,text] }
when (text = @ss.scan(/ADD/))
action { [:AROP,text] }
when (text = @ss.scan(/SUB/))
action { [:AROP,text] }
when (text = @ss.scan(/MULL/))
action { [:AROP,text] }
when (text = @ss.scan(/MULH/))
action { [:AROP,text] }
when (text = @ss.scan(/MULUL/))
action { [:AROP,text] }
when (text = @ss.scan(/MULUH/))
action { [:AROP,text] }
when (text = @ss.scan(/DIVL/))
action { [:AROP,text] }
when (text = @ss.scan(/DIVH/))
action { [:AROP,text] }
when (text = @ss.scan(/DIVUL/))
action { [:AROP,text] }
when (text = @ss.scan(/DIVUH/))
action { [:AROP,text] }
when (text = @ss.scan(/NEG/))
action { [:AROP,text] }
when (text = @ss.scan(/CMP/))
action { [:AROP,text] }
when (text = @ss.scan(/ADC/))
action { [:AROP,text] }
when (text = @ss.scan(/SBB/))
action { [:AROP,text] }
when (text = @ss.scan(/HLT/))
action { [:HLT,text] }
when (text = @ss.scan(/\w+/))
action { [:IDENT,text] }
else
text = @ss.string[@ss.pos .. -1]
raise ScanError, "can not match: '" + text + "'"
end # if
else
raise ScanError, "undefined state: '" + state.to_s + "'"
end # case state
token
end # def _next_token
def tokenize(code)
scan_setup(code)
tokens = []
while token = next_token
tokens << token
end
tokens
end
def make_bytes(val)
bytes=[]
8.times do |i|
mask=0xFF << i*8
byte=(val&mask) >> i*8
bytes.push byte
end
return bytes
end
end # class

3
maskrom Normal file
View File

@ -0,0 +1,3 @@
v3.0 hex words addressed
0: 0000000000000000 00000000000000ff 000000000000ffff 0000000000ffffff 00000000ffffffff 0000000000000000 0000000000000000 0000000000000000
8: ffffffffffffffff 0000000000000000 0000000000000000 0000000000000000 0000000000000000 0000000000000000 0000000000000000 0000000000000000

591
parser.rb Normal file
View File

@ -0,0 +1,591 @@
#
# DO NOT MODIFY!!!!
# This file is automatically generated by Racc 1.4.14
# from Racc grammer file "".
#
require 'racc/parser.rb'
class T64 < Racc::Parser
module_eval(<<'...end t64.y/module_eval...', 't64.y', 64)
def parse(input)
scan_str(input)
end
def get_label(label)
if @labels[label]
return make_bytes(@labels[label])
else
return [label]+[0]*7
end
end
def make_bytes(val)
bytes=[]
8.times do |i|
mask=0xFF << i*8
byte=(val&mask) >> i*8
bytes.push byte
end
return bytes
end
def defed_label(label)
newcode=[]
for line in @code
for index in line.each_index.select {|index| line[index]==label}
line[index,8]=make_bytes(@labels[label])
end
newcode.push line
end
@code=newcode
end
...end t64.y/module_eval...
##### State transition tables begin ###
racc_action_table = [
14, 86, 46, 84, 47, 85, 15, 16, 17, 43,
18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
28, 29, 30, 31, 14, 72, 82, 70, 83, 71,
15, 16, 17, 44, 18, 19, 20, 21, 22, 23,
24, 25, 26, 27, 28, 29, 30, 31, 75, 67,
45, 103, 68, 76, 104, 74, 92, 50, -4, 93,
6, 7, 48, 51, 49, 6, 7, 6, 7, 52,
53, 55, 56, 57, 58, 59, 60, 61, 62, 63,
64, 65, 66, 69, 73, 77, 78, 79, 80, 81,
87, 88, 89, 90, 91, 94, 95, 96, 97, 98,
99, 100, 101, 102, 105, 106, 107, 108, 109, 110,
111, 112, 113, 114, 115, 116, 117, 118, 119, 120,
121, 122, 123, 124, 125, 126, 127, 128, 129, 130,
131, 132, 133, 134, 135, 136, 137, 138, 139, 140,
141, 142, 143, 144, 3, 145, 9, 10, -7, 12,
-10, 35, 36, 37, 38, 39, 40, 41, 42 ]
racc_action_check = [
8, 64, 25, 64, 25, 64, 8, 8, 8, 22,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 34, 55, 63, 55, 63, 55,
34, 34, 34, 23, 34, 34, 34, 34, 34, 34,
34, 34, 34, 34, 34, 34, 34, 34, 57, 48,
24, 84, 48, 57, 84, 57, 70, 27, 10, 70,
10, 10, 26, 29, 26, 11, 11, 2, 2, 30,
31, 35, 36, 37, 38, 39, 40, 41, 42, 43,
44, 45, 46, 50, 56, 58, 59, 60, 61, 62,
65, 66, 67, 68, 69, 72, 76, 77, 78, 79,
80, 81, 82, 83, 85, 86, 91, 92, 93, 94,
95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
105, 106, 107, 110, 112, 113, 114, 115, 116, 118,
121, 122, 125, 126, 127, 128, 129, 133, 134, 135,
136, 138, 139, 140, 1, 141, 3, 5, 6, 7,
12, 14, 15, 16, 17, 18, 19, 20, 21 ]
racc_action_pointer = [
nil, 144, 65, 146, nil, 145, 148, 145, -5, nil,
58, 63, 148, nil, 145, 146, 147, 148, 149, 150,
151, 152, 3, 27, 42, -6, 54, 51, nil, 53,
59, 60, nil, nil, 19, 64, 65, 66, 67, 68,
69, 70, 71, 72, 73, 78, 79, nil, 46, nil,
76, nil, nil, nil, nil, 19, 74, 45, 79, 80,
81, 82, 83, 18, -5, 81, 82, 83, 84, 86,
53, nil, 87, nil, nil, nil, 93, 90, 91, 92,
93, 94, 96, 95, 48, 96, 97, nil, nil, nil,
nil, 103, 98, 99, 103, 101, 105, 102, 107, 104,
109, 107, 114, 109, 110, 117, 115, 113, nil, nil,
114, nil, 117, 118, 119, 120, 121, nil, 120, nil,
nil, 121, 122, nil, nil, 118, 119, 120, 121, 122,
nil, nil, nil, 130, 131, 132, 133, nil, 131, 132,
133, 135, nil, nil, nil, nil ]
racc_action_default = [
-1, -43, -11, -43, -2, -43, -5, -43, -43, 146,
-11, -11, -8, -12, -43, -43, -43, -43, -43, -43,
-43, -43, -43, -43, -43, -43, -43, -43, -39, -43,
-43, -43, -3, -6, -43, -43, -43, -43, -43, -43,
-43, -43, -43, -43, -43, -43, -43, -37, -43, -36,
-43, -40, -41, -42, -9, -43, -43, -43, -43, -43,
-43, -43, -43, -43, -43, -43, -43, -43, -43, -43,
-43, -14, -43, -17, -18, -19, -43, -43, -43, -43,
-43, -43, -43, -43, -43, -43, -43, -32, -33, -34,
-35, -43, -43, -43, -43, -43, -43, -43, -43, -43,
-43, -43, -43, -43, -43, -43, -43, -43, -13, -16,
-43, -20, -43, -43, -43, -43, -43, -26, -43, -28,
-31, -43, -43, -38, -15, -43, -43, -43, -43, -43,
-27, -29, -30, -43, -43, -43, -43, -25, -43, -43,
-43, -43, -21, -22, -23, -24 ]
racc_goto_table = [
13, 4, 1, 2, 11, 34, nil, nil, nil, 32,
33, nil, nil, nil, nil, nil, nil, nil, nil, nil,
nil, nil, nil, nil, nil, nil, 54 ]
racc_goto_check = [
6, 2, 1, 3, 5, 7, nil, nil, nil, 2,
2, nil, nil, nil, nil, nil, nil, nil, nil, nil,
nil, nil, nil, nil, nil, nil, 6 ]
racc_goto_pointer = [
nil, 2, -1, 3, nil, -2, -8, -7, nil ]
racc_goto_default = [
nil, nil, nil, nil, 5, nil, nil, nil, 8 ]
racc_reduce_table = [
0, 0, :racc_error,
0, 32, :_reduce_1,
2, 30, :_reduce_2,
3, 31, :_reduce_3,
2, 31, :_reduce_4,
0, 34, :_reduce_5,
3, 31, :_reduce_6,
1, 31, :_reduce_7,
0, 36, :_reduce_8,
4, 33, :_reduce_9,
2, 33, :_reduce_10,
0, 37, :_reduce_11,
2, 33, :_reduce_12,
6, 35, :_reduce_13,
4, 35, :_reduce_14,
7, 35, :_reduce_15,
6, 35, :_reduce_16,
4, 35, :_reduce_17,
4, 35, :_reduce_18,
4, 35, :_reduce_19,
6, 35, :_reduce_20,
10, 35, :_reduce_21,
10, 35, :_reduce_22,
10, 35, :_reduce_23,
10, 35, :_reduce_24,
8, 35, :_reduce_25,
6, 35, :_reduce_26,
7, 35, :_reduce_27,
6, 35, :_reduce_28,
7, 35, :_reduce_29,
7, 35, :_reduce_30,
6, 35, :_reduce_31,
4, 35, :_reduce_32,
4, 35, :_reduce_33,
4, 35, :_reduce_34,
4, 35, :_reduce_35,
2, 35, :_reduce_36,
2, 35, :_reduce_37,
6, 35, :_reduce_38,
1, 35, :_reduce_39,
2, 35, :_reduce_40,
2, 35, :_reduce_41,
2, 35, :_reduce_42 ]
racc_reduce_n = 43
racc_shift_n = 146
racc_token_table = {
false => 0,
:error => 1,
:NEWLINE => 2,
:IDENT => 3,
:COLON => 4,
:LDB => 5,
:REG => 6,
:COMMA => 7,
:LPAREN => 8,
:RPAREN => 9,
:NUM => 10,
:LDW => 11,
:LD => 12,
:ARB => 13,
:AROP => 14,
:ARIB => 15,
:ARW => 16,
:ARI => 17,
:AR => 18,
:ST => 19,
:STB => 20,
:JNC => 21,
:JNZ => 22,
:JMP => 23,
:JST => 24,
:HLT => 25,
:DB => 26,
:DQW => 27,
:ORG => 28 }
racc_nt_base = 29
racc_use_result_var = true
Racc_arg = [
racc_action_table,
racc_action_check,
racc_action_default,
racc_action_pointer,
racc_goto_table,
racc_goto_check,
racc_goto_default,
racc_goto_pointer,
racc_nt_base,
racc_reduce_table,
racc_token_table,
racc_shift_n,
racc_reduce_n,
racc_use_result_var ]
Racc_token_to_s_table = [
"$end",
"error",
"NEWLINE",
"IDENT",
"COLON",
"LDB",
"REG",
"COMMA",
"LPAREN",
"RPAREN",
"NUM",
"LDW",
"LD",
"ARB",
"AROP",
"ARIB",
"ARW",
"ARI",
"AR",
"ST",
"STB",
"JNC",
"JNZ",
"JMP",
"JST",
"HLT",
"DB",
"DQW",
"ORG",
"$start",
"start",
"program",
"@1",
"line",
"@2",
"ins",
"@3",
"@4" ]
Racc_debug_parser = false
##### State transition tables end #####
# reduce 0 omitted
module_eval(<<'.,.,', 't64.y', 3)
def _reduce_1(val, _values, result)
@code=[]
@labels={}
@ops=["NOT","AND","OR","ADD","SUB","MULL","MULH","MULUL","MULUH",
"DIVL","DIVH","DIVUL","DIVUH","NEG","CMP","ADC","SBB"]
@pos=0
@backpatches={}
@linestarts=[]
@lineends=[]
result
end
.,.,
module_eval(<<'.,.,', 't64.y', 11)
def _reduce_2(val, _values, result)
return @code,@labels,@linestarts,@lineends
result
end
.,.,
module_eval(<<'.,.,', 't64.y', 12)
def _reduce_3(val, _values, result)
result
end
.,.,
module_eval(<<'.,.,', 't64.y', 12)
def _reduce_4(val, _values, result)
result
end
.,.,
module_eval(<<'.,.,', 't64.y', 12)
def _reduce_5(val, _values, result)
@linestarts.push @pos;@lineends.push @pos
result
end
.,.,
module_eval(<<'.,.,', 't64.y', 12)
def _reduce_6(val, _values, result)
result
end
.,.,
module_eval(<<'.,.,', 't64.y', 12)
def _reduce_7(val, _values, result)
@linestarts.push @pos;@lineends.push @pos
result
end
.,.,
module_eval(<<'.,.,', 't64.y', 13)
def _reduce_8(val, _values, result)
@startpos=@pos
result
end
.,.,
module_eval(<<'.,.,', 't64.y', 14)
def _reduce_9(val, _values, result)
@labels[val[0]]=@startpos
defed_label(val[0])
@linestarts.push @startpos
@lineends.push @pos
result
end
.,.,
module_eval(<<'.,.,', 't64.y', 20)
def _reduce_10(val, _values, result)
@labels[val[0]]=@pos
defed_label(val[0])
@linestarts.push @pos
@lineends.push @pos
result
end
.,.,
module_eval(<<'.,.,', 't64.y', 25)
def _reduce_11(val, _values, result)
@startpos=@pos
result
end
.,.,
module_eval(<<'.,.,', 't64.y', 26)
def _reduce_12(val, _values, result)
@linestarts.push @startpos
@lineends.push @pos
result
end
.,.,
module_eval(<<'.,.,', 't64.y', 29)
def _reduce_13(val, _values, result)
@code.push([0x0,0x10|val[1],0x0,*get_label(val[4])]);@pos+=0x10
result
end
.,.,
module_eval(<<'.,.,', 't64.y', 30)
def _reduce_14(val, _values, result)
@code.push([0x0,val[1],0x0,*val[3][0,1]]);@pos+=0x10
result
end
.,.,
module_eval(<<'.,.,', 't64.y', 31)
def _reduce_15(val, _values, result)
@code.push([0x0,0x30|val[1],val[3]<<4|val[5],*val[3,1]]);@pos+=0x10
result
end
.,.,
module_eval(<<'.,.,', 't64.y', 32)
def _reduce_16(val, _values, result)
@code.push([0x0,0x20|val[1],val[4]<<4]);@pos+=0x10
result
end
.,.,
module_eval(<<'.,.,', 't64.y', 33)
def _reduce_17(val, _values, result)
@code.push([0x1,val[1],0x0,*val[3][0,2]]);@pos+=0x10
result
end
.,.,
module_eval(<<'.,.,', 't64.y', 34)
def _reduce_18(val, _values, result)
@code.push([0x03,val[1],0x0,*val[3]]);@pos+=0x10
result
end
.,.,
module_eval(<<'.,.,', 't64.y', 35)
def _reduce_19(val, _values, result)
@code.push([0x03,val[1],0x0,*get_label(val[3])]);@pos+=0x10
result
end
.,.,
module_eval(<<'.,.,', 't64.y', 36)
def _reduce_20(val, _values, result)
@code.push([0x03,0x10|val[1],0x0,*get_label(val[4])]);@pos+=0x10
result
end
.,.,
module_eval(<<'.,.,', 't64.y', 37)
def _reduce_21(val, _values, result)
@code.push([0x8,0x70|val[1],(val[3]<<4)|val[5],@ops.index(val[7])|(val[9][0]<<7)]);@pos+=0x10
result
end
.,.,
module_eval(<<'.,.,', 't64.y', 38)
def _reduce_22(val, _values, result)
@code.push([0x8,0x80|val[1],(val[3]<<4),@ops.index(val[7]),val[5][0]]);@pos+=0x10
result
end
.,.,
module_eval(<<'.,.,', 't64.y', 39)
def _reduce_23(val, _values, result)
@code.push([0x9,0x70|val[1],(val[3]<<4)|val[5],@ops.index(val[7])|(val[9][0]<<7)]);@pos+=0x10
result
end
.,.,
module_eval(<<'.,.,', 't64.y', 40)
def _reduce_24(val, _values, result)
@code.push([0xb,0x80|val[1],(val[3]<<4),@ops.index(val[7])|((val[9][0])<<7),*val[5]]);@pos+=0x10
result
end
.,.,
module_eval(<<'.,.,', 't64.y', 41)
def _reduce_25(val, _values, result)
@code.push([0xb,0x70|val[1],(val[3]<<4)|val[5],@ops.index(val[7])]);@pos+=0x10
result
end
.,.,
module_eval(<<'.,.,', 't64.y', 42)
def _reduce_26(val, _values, result)
@code.push([0x7,0x20,(val[4]<<4|val[1])]);@pos+=0x10
result
end
.,.,
module_eval(<<'.,.,', 't64.y', 43)
def _reduce_27(val, _values, result)
@code.push([0x7,0x40,val[1],*get_label(val[5]),*val[3][0,4]]);@pos+=0x10
result
end
.,.,
module_eval(<<'.,.,', 't64.y', 44)
def _reduce_28(val, _values, result)
@code.push([0x4,0x10,val[1],*get_label(val[4])]);@pos+=0x10
result
end
.,.,
module_eval(<<'.,.,', 't64.y', 45)
def _reduce_29(val, _values, result)
@code.push([0x4,0x90,val[1],*get_label(val[5]),*val[3][0,4]]);@pos+=0x10
result
end
.,.,
module_eval(<<'.,.,', 't64.y', 46)
def _reduce_30(val, _values, result)
@code.push([0x4,0x20,(val[5]<<4|val[1]),val[3]]);@pos+=0x10
result
end
.,.,
module_eval(<<'.,.,', 't64.y', 47)
def _reduce_31(val, _values, result)
@code.push([0x4,0x20,(val[4]<<4)|val[1]]);@pos+=0x10
result
end
.,.,
module_eval(<<'.,.,', 't64.y', 48)
def _reduce_32(val, _values, result)
@code.push([0x10,0x10,0x0,*get_label(val[2])]);@pos+=0x10
result
end
.,.,
module_eval(<<'.,.,', 't64.y', 49)
def _reduce_33(val, _values, result)
@code.push([0xe,0x10,0x0,*get_label(val[2])]);@pos+=0x10
result
end
.,.,
module_eval(<<'.,.,', 't64.y', 50)
def _reduce_34(val, _values, result)
@code.push([0xc,0x10,0x0,*get_label(val[2])]);@pos+=0x10
result
end
.,.,
module_eval(<<'.,.,', 't64.y', 51)
def _reduce_35(val, _values, result)
@code.push([0xc,0x20,val[2]<<4]);@pos+=0x10
result
end
.,.,
module_eval(<<'.,.,', 't64.y', 52)
def _reduce_36(val, _values, result)
@code.push([0xc,0x10,0x0,*val[1]]);@pos+=0x10
result
end
.,.,
module_eval(<<'.,.,', 't64.y', 53)
def _reduce_37(val, _values, result)
@code.push([0xe,0x10,0x0,*val[1]]);@pos+=0x10
result
end
.,.,
module_eval(<<'.,.,', 't64.y', 54)
def _reduce_38(val, _values, result)
@code.push([0x11,0x10|val[1],0x0,*get_label(val[4])]);@pos+=0x10
result
end
.,.,
module_eval(<<'.,.,', 't64.y', 55)
def _reduce_39(val, _values, result)
@code.push([0xFF]);@pos+=0x10
result
end
.,.,
module_eval(<<'.,.,', 't64.y', 56)
def _reduce_40(val, _values, result)
@code.push([*val[1][0,1]]);@pos+=1
result
end
.,.,
module_eval(<<'.,.,', 't64.y', 57)
def _reduce_41(val, _values, result)
@code.push([*val[1]]);@pos+=8
result
end
.,.,
module_eval(<<'.,.,', 't64.y', 58)
def _reduce_42(val, _values, result)
@pos=val[1].pack("C*").unpack("Q<")
result
end
.,.,
def _reduce_none(val, _values, result)
val[0]
end
end # class T64

2
progs/call.bin Normal file
View File

@ -0,0 +1,2 @@
v2.0 raw
3 0 0 a 0 0 0 0 0 0 0 3 0 0 0 2 0 0 0 0 0 0 11 1f 0 37 0 0 0 0 0 0 0 11 1f 0 37 0 0 0 0 0 0 0 c 10 0 2c 0 0 0 0 0 0 0 b 80 0 4 8 0 0 0 0 0 0 0 7 20 f0 b 70 0 5 b 80 0 3 2 0 0 0 0 0 0 0 3 2f 0 b 80 0 3 8 0 0 0 0 0 0 0 c 20 f0

16
progs/call.lst Normal file
View File

@ -0,0 +1,16 @@
0000: 03 00 00 0a 00 00 00 00 00 00 00 LD r0,10
000b: 03 0e 00 00 02 00 00 00 00 00 00 LD r14,0x200
0016: 11 1f 00 37 00 00 00 00 00 00 00 JST reta,(sub)
0021: 11 1f 00 37 00 00 00 00 00 00 00 JST reta,(sub)
002c: 0c 10 00 2c 00 00 00 00 00 00 00 hlt: JMP (hlt)
0037: 0b 8e e0 04 08 00 00 00 00 00 00 00 ARI r14,r14,8,SUB
0043: 07 20 ef ST reta,(r14)
0046: 0b 70 00 05 AR r0,r0,r0,MULL
004a: 0b 80 00 03 02 00 00 00 00 00 00 00 ARI r0,r0,2,ADD
0056: 03 2f e0 LD reta,(r14)
0059: 0b 8e e0 03 08 00 00 00 00 00 00 00 ARI r14,r14,8,ADD
0065: 0c 20 f0 JMP (reta)
Symbol table:
hlt: 0000002c
sub: 00000037

13
progs/call.t64 Normal file
View File

@ -0,0 +1,13 @@
LD r0,10
LD r14,0x200
JST reta,(sub)
JST reta,(sub)
hlt: JMP (hlt)
sub:
ARI r14,r14,8,SUB
ST reta,(r14)
AR r0,r0,r0,MULL
ARI r0,r0,2,ADD
LD reta,(r14)
ARI r14,r14,8,ADD
JMP (reta)

2
progs/inc.bin Normal file
View File

@ -0,0 +1,2 @@
v2.0 raw
0 10 0 3b 0 0 0 0 0 0 0 0 10 0 3c 0 0 0 0 0 0 0 8 70 0 3 4 10 0 3b 0 0 0 0 0 0 0 10 10 0 16 0 0 0 0 0 0 0 c 10 0 30 0 0 0 0 0 0 0 0 1

14
progs/inc.lst Normal file
View File

@ -0,0 +1,14 @@
0000: 00 10 00 3b 00 00 00 00 00 00 00 LDB r0,(count)
000b: 00 10 00 3c 00 00 00 00 00 00 00 LDB r1,(incsize)
0016: 08 70 00 03 loop: ARB r0,r0,r1,ADD,1
001a: 04 10 00 3b 00 00 00 00 00 00 00 STB r0,(count)
0025: 10 10 00 16 00 00 00 00 00 00 00 JNC (loop)
0030: 0c 10 00 30 00 00 00 00 00 00 00 hlt: JMP (hlt)
003b: 00 count: db 0
003c: 01 incsize: db 1
Symbol table:
loop: 00000016
hlt: 00000030
count: 0000003b
incsize: 0000003c

8
progs/inc.t64 Normal file
View File

@ -0,0 +1,8 @@
LDB r0,(count)
LDB r1,(incsize)
loop: ARB r0,r0,r1,ADD,1
STB r0,(count)
JNC (loop)
hlt: JMP (hlt)
count: db 0
incsize: db 1

2
progs/inc2.bin Normal file
View File

@ -0,0 +1,2 @@
v2.0 raw
0 10 0 40 0 0 0 0 0 0 0 00 00 00 00 00 8 80 0 3 1 00 00 00 00 00 00 00 00 00 00 00 4 10 0 40 0 0 0 0 0 0 0 00 00 00 00 00 e 10 0 0 0 0 0 0 0 0 0 00 00 00 00 00 0 0 0 0 0 0 0 0

11
progs/inc2.hex Normal file
View File

@ -0,0 +1,11 @@
0000000050001000
0000000000000000
0000000103008008
0000000000000000
0000000050001004
0000000000000000
000000000000100e
0000000000000000
00000000000000ff
0000000000000000
0000000000000000

9
progs/inc2.lst Normal file
View File

@ -0,0 +1,9 @@
0000: 00 10 00 50 00 00 00 00 00 00 00 LDB r0,(count)
0010: 08 80 00 03 01 ARIB r0,r0,1,ADD,0
0020: 04 10 00 50 00 00 00 00 00 00 00 STB r0,(count)
0030: 0e 10 00 00 00 00 00 00 00 00 00 JNZ 0
0040: ff HLT
0050: 00 00 00 00 00 00 00 00 count: dqw 0
Symbol table:
count: 00000050

6
progs/inc2.t64 Normal file
View File

@ -0,0 +1,6 @@
LDB r0,(count)
ARIB r0,r0,1,ADD,0
STB r0,(count)
JNZ 0
HLT
count: dqw 0

20
progs/incwpaging.t64 Normal file
View File

@ -0,0 +1,20 @@
LDB r0,(count)
LDB r1,(incsize)
loop: ARB r0,r0,r1,ADD,0
STB r0,(count)
JNC (loop)
hlt: JMP (hlt)
count: db 0
incsize: db 1
org 0x100
dqw 0x201
org 0x200
dqw 0x301
org 0x300
dqw 0x401
org 0x400
dqw 0x501
org 0x500
dqw 0x601
org 0x600
dqw 0x001

2
progs/pgtest.bin Normal file
View File

@ -0,0 +1,2 @@
v2.0 raw
3 0 0 2c 0 0 0 0 0 0 0 b 80 0 3 4 0 0 0 0 0 0 0 0 20 0 8 80 0 7 10 8 80 0 3 1 8 80 0 b 10 4 20 0 c 10 0 0 0 0 0 0 0 0 0

11
progs/pgtest.lst Normal file
View File

@ -0,0 +1,11 @@
0000: 03 00 00 2c 00 00 00 00 00 00 00 LD r1,jmp_ins
000b: 0b 80 00 03 04 00 00 00 00 00 00 00 ARI r1,r1,4,ADD,0
0017: 00 20 00 LDB r0,(r1)
001a: 08 80 00 07 10 ARIB r0,r0,16,MULUL,0
001f: 08 80 00 03 01 ARIB r0,r0,1,ADD,0
0024: 08 80 00 0b 10 ARIB r0,r0,16,DIVUL,0
0029: 04 20 00 STB r0,(r1)
002c: 0c 10 00 00 00 00 00 00 00 00 00 jmp_ins: JMP 0x0
Symbol table:
jmp_ins: 0000002c

8
progs/pgtest.t64 Normal file
View File

@ -0,0 +1,8 @@
LD r1,jmp_ins
ARI r1,r1,4,ADD,0
LDB r0,(r1)
ARIB r0,r0,16,MULUL,0
ARIB r0,r0,1,ADD,0
ARIB r0,r0,16,DIVUL,0
STB r0,(r1)
jmp_ins: JMP 0x0

4097
progs/pgtestfixedwtables.bin Normal file

File diff suppressed because it is too large Load Diff

2
progs/rom.bin Normal file
View File

@ -0,0 +1,2 @@
v2.0 raw
3 10 0 62 0 0 0 0 0 0 0 3 10 0 6a 0 0 0 0 0 0 0 b 70 0 3 7 40 0 72 0 0 0 0 0 0 0 8 0 0 0 0 0 0 1 4 90 0 72 0 0 0 0 0 0 0 7 0 0 0 1 0 0 0 2 9 70 0 4 0 30 0 0 4 20 0 0 e 10 0 41 0 0 0 0 0 0 0 c 10 0 62 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

24
progs/rom.lst Normal file
View File

@ -0,0 +1,24 @@
0000: 03 10 00 62 00 00 00 00 00 00 00 LD r0, (rom_size) # - 11
000b: 03 10 00 6a 00 00 00 00 00 00 00 LD r1, (ram_size) # - 11
0016: 0b 70 00 03 AR r2,r0,r1,ADD #r2 contains first free address after ram - 4
001a: 07 40 00 72 00 00 00 00 00 00 00 08 00 00 00 ST r2,8(pci_base) #set BAR0 of hdd to first free address - 15
0029: 00 00 00 01 LDB r4,1 # - 4
002d: 04 90 00 72 00 00 00 00 00 00 00 07 00 00 00 STB r4,7(pci_base) #enable hdd BAR0 - 15
003c: #copy first sector of HDD to RAM start
003c: #r0 is RAM address
003c: 01 00 00 00 02 LDW r1,512 #r1 is index - 5
0041: loop:
0041: 09 70 00 04 ARW r1,r1,r4,SUB #Subtract 1 from the index - 4 (r4 set to 1 on line 5, saves memory for the 1 constant)
0045: 00 30 00 LDB r3,r1(r2) #set r3 to byte from HDD - 3
0048: 00 04 20 00 STB r3,r1(r0) #store HDD byte to RAM - 4
004c: 00 0e 10 00 41 00 00 00 00 00 00 JNZ (loop) #If index not 0, jump back - 11
0057: 00 0c 10 00 62 00 00 00 00 00 00 JMP (rom_size) #Jump to loaded code - 11
0062: 00 00 00 00 00 00 00 00 rom_size: dqw 0
006a: 00 00 00 00 00 00 00 00 ram_size: dqw 0
0072: 00 00 00 00 00 00 00 00 pci_base: dqw 0
Symbol table:
loop: 00000041
rom_size: 00000062
ram_size: 0000006a
pci_base: 00000072

16
progs/rom.t64 Normal file
View File

@ -0,0 +1,16 @@
LD r0, (rom_size) # - 11
LD r1, (ram_size) # - 11
AR r2,r0,r1,ADD #r2 contains first free address after ram - 4
ST r2,8(pci_base) #set BAR0 of hdd to first free address - 15
LDB r4,1 # - 4
STB r4,7(pci_base) #enable hdd BAR0 - 15
LDW r1,512 #r1 is index - 5
loop:
ARW r1,r1,r4,SUB #Subtract 1 from the index - 4 (r4 set to 1 on line 5, saves memory for the 1 constant)
LDB r3,r1(r2) #set r3 to byte from HDD - 3
STB r3,r1(r0) #store HDD byte to RAM - 4
JNZ (loop) #If index not 0, jump back - 11
JMP (rom_size) #Jump to loaded code - 11
rom_size: dqw 0
ram_size: dqw 0
pci_base: dqw 0

80
t64.rex Normal file
View File

@ -0,0 +1,80 @@
class T64
macro
SPACE [\ ]+
rule
reta { [:REG,15] }
r\d+ { [:REG,text.to_i]}
0x[0-9a-f]+ { [:NUM, make_bytes(text.to_i(16))] }
\d+ { [:NUM, make_bytes(text.to_i)] }
\n { [:NEWLINE,"\n"]}
{SPACE} { }
\( { [:LPAREN,"("] }
\) { [:RPAREN,")"] }
, { [:COMMA,","] }
\#.+ {}
: { [:COLON,text]}
LDB { [:LDB,text] }
LDW { [:LDW,text] }
LDDW { [:LDDW,text] }
LD { [:LD,text] }
STB { [:STB,text] }
STW { [:STW,text] }
STDW { [:STDW,text] }
ST { [:ST,text] }
ARIB { [:ARIB,text] }
ARIW { [:ARIW,text] }
ARIDW { [:ARIDW,text] }
ARI { [:ARI,text] }
ARB { [:ARB,text] }
ARW { [:ARW,text] }
ARDW { [:ARDW,text] }
AR { [:AR,text] }
JMP { [:JMP,text] }
JC { [:JC,text] }
JNC { [:JNC,text] }
JZ { [:JZ,text] }
JNZ { [:JNZ,text] }
JST { [:JST,text] }
db { [:DB,text] }
dw { [:DW,text] }
ddw { [:DDW,text] }
dqw { [:DQW,text] }
org { [:ORG,text] }
NOT { [:AROP,text] }
AND { [:AROP,text] }
OR { [:AROP,text] }
ADD { [:AROP,text] }
SUB { [:AROP,text] }
MULL { [:AROP,text] }
MULH { [:AROP,text] }
MULUL { [:AROP,text] }
MULUH { [:AROP,text] }
DIVL { [:AROP,text] }
DIVH { [:AROP,text] }
DIVUL { [:AROP,text] }
DIVUH { [:AROP,text] }
NEG { [:AROP,text] }
CMP { [:AROP,text] }
ADC { [:AROP,text] }
SBB { [:AROP,text] }
HLT { [:HLT,text] }
\w+ { [:IDENT,text] }
inner
def tokenize(code)
scan_setup(code)
tokens = []
while token = next_token
tokens << token
end
tokens
end
def make_bytes(val)
bytes=[]
8.times do |i|
mask=0xFF << i*8
byte=(val&mask) >> i*8
bytes.push byte
end
return bytes
end
end

92
t64.y Normal file
View File

@ -0,0 +1,92 @@
class T64
rule
start: {
@code=[]
@labels={}
@ops=["NOT","AND","OR","ADD","SUB","MULL","MULH","MULUL","MULUH",
"DIVL","DIVH","DIVUL","DIVUH","NEG","CMP","ADC","SBB"]
@pos=0
@backpatches={}
@linestarts=[]
@lineends=[]
} program {return @code,@labels,@linestarts,@lineends}
program: line NEWLINE program {} | line NEWLINE {} | NEWLINE {@linestarts.push @pos;@lineends.push @pos} program {} | NEWLINE {@linestarts.push @pos;@lineends.push @pos}
line: IDENT COLON {@startpos=@pos} ins {
@labels[val[0]]=@startpos
defed_label(val[0])
@linestarts.push @startpos
@lineends.push @pos
}
| IDENT COLON {
@labels[val[0]]=@pos
defed_label(val[0])
@linestarts.push @pos
@lineends.push @pos
}
| {@startpos=@pos} ins {
@linestarts.push @startpos
@lineends.push @pos
}
ins: LDB REG COMMA LPAREN IDENT RPAREN {@code.push([0x0,0x10|val[1],0x0,*get_label(val[4])]);@pos+=0x10}
| LDB REG COMMA NUM {@code.push([0x0,val[1],0x0,*val[3][0,1]]);@pos+=0x10}
| LDB REG COMMA REG LPAREN REG RPAREN {@code.push([0x0,0x30|val[1],val[3]<<4|val[5],*val[3,1]]);@pos+=0x10}
| LDB REG COMMA LPAREN REG RPAREN {@code.push([0x0,0x20|val[1],val[4]<<4]);@pos+=0x10}
| LDW REG COMMA NUM {@code.push([0x1,val[1],0x0,*val[3][0,2]]);@pos+=0x10}
| LD REG COMMA NUM {@code.push([0x03,val[1],0x0,*val[3]]);@pos+=0x10}
| LD REG COMMA IDENT {@code.push([0x03,val[1],0x0,*get_label(val[3])]);@pos+=0x10}
| LD REG COMMA LPAREN IDENT RPAREN {@code.push([0x03,0x10|val[1],0x0,*get_label(val[4])]);@pos+=0x10}
| ARB REG COMMA REG COMMA REG COMMA AROP COMMA NUM {@code.push([0x8,0x70|val[1],(val[3]<<4)|val[5],@ops.index(val[7])|(val[9][0]<<7)]);@pos+=0x10}
| ARIB REG COMMA REG COMMA NUM COMMA AROP COMMA NUM {@code.push([0x8,0x80|val[1],(val[3]<<4),@ops.index(val[7]),val[5][0]]);@pos+=0x10}
| ARW REG COMMA REG COMMA REG COMMA AROP COMMA NUM {@code.push([0x9,0x70|val[1],(val[3]<<4)|val[5],@ops.index(val[7])|(val[9][0]<<7)]);@pos+=0x10}
| ARI REG COMMA REG COMMA NUM COMMA AROP COMMA NUM {@code.push([0xb,0x80|val[1],(val[3]<<4),@ops.index(val[7])|((val[9][0])<<7),*val[5]]);@pos+=0x10}
| AR REG COMMA REG COMMA REG COMMA AROP {@code.push([0xb,0x70|val[1],(val[3]<<4)|val[5],@ops.index(val[7])]);@pos+=0x10}
| ST REG COMMA LPAREN REG RPAREN {@code.push([0x7,0x20,(val[4]<<4|val[1])]);@pos+=0x10}
| ST REG COMMA NUM LPAREN IDENT RPAREN {@code.push([0x7,0x40,val[1],*get_label(val[5]),*val[3][0,4]]);@pos+=0x10}
| STB REG COMMA LPAREN IDENT RPAREN {@code.push([0x4,0x10,val[1],*get_label(val[4])]);@pos+=0x10}
| STB REG COMMA NUM LPAREN IDENT RPAREN {@code.push([0x4,0x90,val[1],*get_label(val[5]),*val[3][0,4]]);@pos+=0x10}
| STB REG COMMA REG LPAREN REG RPAREN {@code.push([0x4,0x20,(val[5]<<4|val[1]),val[3]]);@pos+=0x10}
| STB REG COMMA LPAREN REG RPAREN {@code.push([0x4,0x20,(val[4]<<4)|val[1]]);@pos+=0x10}
| JNC LPAREN IDENT RPAREN {@code.push([0x10,0x10,0x0,*get_label(val[2])]);@pos+=0x10}
| JNZ LPAREN IDENT RPAREN {@code.push([0xe,0x10,0x0,*get_label(val[2])]);@pos+=0x10}
| JMP LPAREN IDENT RPAREN {@code.push([0xc,0x10,0x0,*get_label(val[2])]);@pos+=0x10}
| JMP LPAREN REG RPAREN {@code.push([0xc,0x20,val[2]<<4]);@pos+=0x10}
| JMP NUM {@code.push([0xc,0x10,0x0,*val[1]]);@pos+=0x10}
| JNZ NUM {@code.push([0xe,0x10,0x0,*val[1]]);@pos+=0x10}
| JST REG COMMA LPAREN IDENT RPAREN {@code.push([0x11,0x10|val[1],0x0,*get_label(val[4])]);@pos+=0x10}
| HLT {@code.push([0xFF]);@pos+=0x10}
| DB NUM {@code.push([*val[1][0,1]]);@pos+=1}
| DQW NUM {@code.push([*val[1]]);@pos+=8}
| ORG NUM {@pos=val[1].pack("C*").unpack("Q<")}
end
---- inner
def parse(input)
scan_str(input)
end
def get_label(label)
if @labels[label]
return make_bytes(@labels[label])
else
return [label]+[0]*7
end
end
def make_bytes(val)
bytes=[]
8.times do |i|
mask=0xFF << i*8
byte=(val&mask) >> i*8
bytes.push byte
end
return bytes
end
def defed_label(label)
newcode=[]
for line in @code
for index in line.each_index.select {|index| line[index]==label}
line[index,8]=make_bytes(@labels[label])
end
newcode.push line
end
@code=newcode
end

13
verilog/Makefile Normal file
View File

@ -0,0 +1,13 @@
PROG=prog.vvp
SV_FILES=t64_system.sv
VVP_FILES=$(SV_FILES:.sv=.vvp)
LXT_FILES=$(SV_FILES:.sv=.lxt)
IVFLAGS=-Wall -Wno-sensitivity-entire-array -g2012 -Y .sv -y lib
bin/%.vvp: %.sv lib/*.sv Makefile
iverilog $(IVFLAGS) -o $@ $<
%.lxt: bin/%.vvp Makefile
vvp $< -lxt2
run: $(LXT_FILES) Makefile

10
verilog/addrtrans.txt Normal file
View File

@ -0,0 +1,10 @@
0 IMMVAL
1 MEMADDR
2 APOINT
3 BOFFRR
4 BOFFRI
5 BOFFIR
6 BOFFII
7 ALU
8 ALUI
9 BOFFRR2

0
verilog/alu_if_tb.sv Normal file
View File

37
verilog/alu_tb.sv Normal file
View File

@ -0,0 +1,37 @@
module alu_tb();
logic [63:0] a,b,r;
logic [7:0] op;
logic [1:0] width;
logic cin,zero,carry,setcarry,setr;
alu DUT (
.a(a),
.b(b),
.op(op),
.cin(cin),
.width(width),
.r(r),
.zero(zero),
.carry(carry),
.setcarry(setcarry),
.setr(setr)
);
initial begin
$dumpfile("dumps/alu.vcd");
$dumpvars(0,alu_tb);
width=2'h0;
cin=1'b0;
a=64'hFF;
b=64'h0;
op=8'h0;
#1;
a=8'hA8;
b=8'h22;
op=8'h1;
#1;
$finish;
end
endmodule

256
verilog/aluoptrans.txt Normal file
View File

@ -0,0 +1,256 @@
00 NOT
01 AND
02 OR
03 ADD
04 SUB
05 MULL
06 MULH
07 MULUL
08 MULUH
09 DIVL
0a DIVH
0b DIVUL
0c DIVUH
0d NEG
0e ADC
0f SBB
10 CMP
11 INVAL
12 INVAL
13 INVAL
14 INVAL
15 INVAL
16 INVAL
17 INVAL
18 INVAL
19 INVAL
1a INVAL
1b INVAL
1c INVAL
1d INVAL
1e INVAL
1f INVAL
20 INVAL
21 INVAL
22 INVAL
23 INVAL
24 INVAL
25 INVAL
26 INVAL
27 INVAL
28 INVAL
29 INVAL
2a INVAL
2b INVAL
2c INVAL
2d INVAL
2e INVAL
2f INVAL
30 INVAL
31 INVAL
32 INVAL
33 INVAL
34 INVAL
35 INVAL
36 INVAL
37 INVAL
38 INVAL
39 INVAL
3a INVAL
3b INVAL
3c INVAL
3d INVAL
3e INVAL
3f INVAL
40 INVAL
41 INVAL
42 INVAL
43 INVAL
44 INVAL
45 INVAL
46 INVAL
47 INVAL
48 INVAL
49 INVAL
4a INVAL
4b INVAL
4c INVAL
4d INVAL
4e INVAL
4f INVAL
50 INVAL
51 INVAL
52 INVAL
53 INVAL
54 INVAL
55 INVAL
56 INVAL
57 INVAL
58 INVAL
59 INVAL
5a INVAL
5b INVAL
5c INVAL
5d INVAL
5e INVAL
5f INVAL
60 INVAL
61 INVAL
62 INVAL
63 INVAL
64 INVAL
65 INVAL
66 INVAL
67 INVAL
68 INVAL
69 INVAL
6a INVAL
6b INVAL
6c INVAL
6d INVAL
6e INVAL
6f INVAL
70 INVAL
71 INVAL
72 INVAL
73 INVAL
74 INVAL
75 INVAL
76 INVAL
77 INVAL
78 INVAL
79 INVAL
7a INVAL
7b INVAL
7c INVAL
7d INVAL
7e INVAL
7f INVAL
80 NOT B0
81 AND B0
82 OR B0
83 ADD B0
84 SUB B0
85 MULL B0
86 MULH B0
87 MULUL B0
88 MULUH B0
89 DIVL B0
8a DIVH B0
8b DIVUL B0
8c DIVUH B0
8d NEG B0
8e ADC B0
8f SBB B0
90 CMP B0
91 INVAL
92 INVAL
93 INVAL
94 INVAL
95 INVAL
96 INVAL
97 INVAL
98 INVAL
99 INVAL
9a INVAL
9b INVAL
9c INVAL
9d INVAL
9e INVAL
9f INVAL
a0 INVAL
a1 INVAL
a2 INVAL
a3 INVAL
a4 INVAL
a5 INVAL
a6 INVAL
a7 INVAL
a8 INVAL
a9 INVAL
aa INVAL
ab INVAL
ac INVAL
ad INVAL
ae INVAL
af INVAL
b0 INVAL
b1 INVAL
b2 INVAL
b3 INVAL
b4 INVAL
b5 INVAL
b6 INVAL
b7 INVAL
b8 INVAL
b9 INVAL
ba INVAL
bb INVAL
bc INVAL
bd INVAL
be INVAL
bf INVAL
c0 INVAL
c1 INVAL
c2 INVAL
c3 INVAL
c4 INVAL
c5 INVAL
c6 INVAL
c7 INVAL
c8 INVAL
c9 INVAL
ca INVAL
cb INVAL
cc INVAL
cd INVAL
ce INVAL
cf INVAL
d0 INVAL
d1 INVAL
d2 INVAL
d3 INVAL
d4 INVAL
d5 INVAL
d6 INVAL
d7 INVAL
d8 INVAL
d9 INVAL
da INVAL
db INVAL
dc INVAL
dd INVAL
de INVAL
df INVAL
e0 INVAL
e1 INVAL
e2 INVAL
e3 INVAL
e4 INVAL
e5 INVAL
e6 INVAL
e7 INVAL
e8 INVAL
e9 INVAL
ea INVAL
eb INVAL
ec INVAL
ed INVAL
ee INVAL
ef INVAL
f0 INVAL
f1 INVAL
f2 INVAL
f3 INVAL
f4 INVAL
f5 INVAL
f6 INVAL
f7 INVAL
f8 INVAL
f9 INVAL
fa INVAL
fb INVAL
fc INVAL
fd INVAL
fe INVAL
ff INVAL

10761
verilog/bin/mmu_tb.vvp Executable file

File diff suppressed because one or more lines are too long

10433
verilog/bin/tlb_tb.vvp Executable file

File diff suppressed because one or more lines are too long

BIN
verilog/dumps/mmu.vcd Normal file

Binary file not shown.

BIN
verilog/dumps/t64.lxt Normal file

Binary file not shown.

BIN
verilog/dumps/tlb.lxt Normal file

Binary file not shown.

BIN
verilog/dumps/tlb4096.fst Normal file

Binary file not shown.

110
verilog/lib/alu.sv Normal file
View File

@ -0,0 +1,110 @@
module alun #(parameter width = 8)
(input[7:0] op,
input[63:0] ain,bin,
input cin,
output logic[63:0] rout,
output logic zero,carry,setcarry,setr);
logic[width-1:0] a,b,r;
logic[width:0] rwc;
logic [127:0] r128;
logic signed [width-1:0] asigned,bsigned;
always @(*) begin
a=ain[width-1:0];
b=(op[7]) ? 0 : bin[width-1:0];
carry=0;
setcarry=0;
setr=1;
case(op[6:0])
0: r=~a;
1: r=a&b;
2: r=a|b;
3: begin
rwc=a+b;
r=rwc[width-1:0];
carry=rwc[width:width];
setcarry=1;
end
4: begin
rwc=a-b;
r=rwc[width-1:0];
carry=rwc[width:width];
setcarry=1;
end
5: begin
asigned=a;
bsigned=b;
r=asigned*bsigned;
end
6: begin
asigned=a;
bsigned=b;
r128=asigned*bsigned;
r=r128[127:64];
end
7: r=a*b;
8: begin
r128=a*b;
r=r128[127:64];
end
9: begin
asigned=a;
bsigned=b;
r=asigned/bsigned;
end
10: begin
asigned=a;
bsigned=b;
r128=asigned/bsigned;
r=r128[127:64];
end
11: r=a/b;
12: begin
r128=a/b;
r=r128[127:64];
end
13: begin
asigned=a;
r=~a;
end
14: begin
rwc=a+b+cin;
r=rwc[width-1:0];
carry=rwc[width:width];
setcarry=1;
end
// 15 is SBB
16: begin
rwc=a-b;
carry=rwc[width:width];
setcarry=1;
setr=0;
end
default: r=0;
endcase
zero=(r==0);
rout=r;
end
endmodule
module alu(input[7:0] op,
input[63:0] a,b,
input cin,
input[1:0] width,
output logic[63:0] r,
output logic zero,carry,setcarry,setr);
wire[63:0] rs[4];
wire zeros[4],carrys[4],setcarrys[4],setrs[4];
alun #(8) alu8(op,a,b,cin,rs[0],zeros[0],carrys[0],setcarrys[0],setrs[0]);
alun #(16) alu16(op,a,b,cin,rs[1],zeros[1],carrys[1],setcarrys[1],setrs[1]);
alun #(32) alu32(op,a,b,cin,rs[2],zeros[2],carrys[2],setcarrys[2],setrs[2]);
alun #(64) alu64(op,a,b,cin,rs[3],zeros[3],carrys[3],setcarrys[3],setrs[3]);
always @(*) begin
r=rs[width];
zero=zeros[width];
carry=carrys[width];
setcarry=setcarrys[width];
setr=setrs[width];
end
endmodule

30
verilog/lib/alu_if.sv Normal file
View File

@ -0,0 +1,30 @@
module alu_if (input[63:0] rdaout,rdbout,imm,
input[7:0] aluop,
input[1:0] width,
input clk,reset,immload,aluload,
output wire[63:0] aluout,
output wire zero,carry,setr
);
logic carryff;
logic zeroff;
wire carryffin;
wire zeroffin;
wire setcarry;
wire[63:0] bin;
assign bin=(immload) ? imm : rdaout;
alu arlu(aluop,rdaout,bin,carryff,width,aluout,zeroffin,carryffin,setcarry,setr);
assign carry=carryff;
assign zero=zeroff;
always @ (posedge clk or reset) begin
if(reset) begin
carryff<=0;
zeroff<=0;
end
else if(clk) begin
if(setcarry)
carryff<=carryffin;
if(aluload)
zeroff<=zeroffin;
end
end
endmodule

101
verilog/lib/control.sv Normal file
View File

@ -0,0 +1,101 @@
module control (input[63:0] opf8,opl8,
input exec,carry,zero,
output logic[63:0] imm,
output wire[7:0] aluop,
output wire[3:0] wrsel,rdasel,rdbsel,
output reg[1:0] width,
output wire retload,
output reg regwr,memwr,aluload,jump,immload,memaddr,pointer,specialwr,iret);
wire[7:0] opcode;
wire[3:0] addrmode;
reg[1:0] opwidth;
reg regwrop,memwrop,jumpop,specialwrop;
assign opcode=opf8[7:0];
assign addrmode=opf8[15:12];
assign wrsel=opf8[11:8];
assign rdasel=opf8[23:20];
assign rdbsel=opf8[19:16];
assign aluop=opf8[31:24];
assign regwr=regwrop&exec;
assign memwr=memwrop&exec;
assign jump=jumpop&exec;
assign specialwr=(opcode==18)&exec;
assign iret=(opcode==19)&exec;
assign retload=(opcode==8'h11);
always @ ( * ) begin
case (opcode)
0: opwidth=0;
1: opwidth=1;
2: opwidth=2;
3: opwidth=3;
4: opwidth=0;
5: opwidth=1;
6: opwidth=2;
7: opwidth=3;
8: opwidth=0;
9: opwidth=1;
10: opwidth=2;
11: opwidth=3;
default: opwidth=0;
endcase
if (exec)
width=opwidth;
else
width=3;
case (opcode)
0: regwrop=1;
1: regwrop=1;
2: regwrop=1;
3: regwrop=1;
8: regwrop=1;
9: regwrop=1;
10: regwrop=1;
11: regwrop=1;
17: regwrop=1;
default: regwrop=0;
endcase
immload=0;
memaddr=0;
pointer=0;
case (addrmode)
0: immload=1;
1: memaddr=1;
2: pointer=1;
8: immload=1;
default: ;
endcase
if(addrmode==8) begin
imm[31:0]=opf8[63:32];
imm[63:32]=opl8[31:0];
end
else begin
imm[39:0]=opf8[63:24];
imm[63:40]=opl8[31:0];
end
case (opcode)
4: memwrop=1;
5: memwrop=1;
6: memwrop=1;
7: memwrop=1;
default: memwrop=0;
endcase
case (opcode)
8: aluload=1;
9: aluload=1;
10: aluload=1;
11: aluload=1;
default: aluload=0;
endcase
case (opcode)
12: jumpop=1;
13: jumpop=1&zero;
14: jumpop=1&~zero;
15: jumpop=1&carry;
16: jumpop=1&~carry;
17: jumpop=1;
default: jumpop=0;
endcase
end
endmodule // control

26
verilog/lib/mmu.sv Normal file
View File

@ -0,0 +1,26 @@
module mmu (input [63:0] addrin,din,pl6pdata,
input reset,memcycle,clk,pl6pwr,pgen,stopwalk,
output [63:0] addrout,
output [1:0] width,
output pgstrctwalk,pgft);
logic [63:0] fetchedentry;
wire [63:0] hitentry,walkaddr;
logic [12:0] tlbwraddr=0;
logic tlbwr,hit;
tlb trlb({12'b0,addrin[63:12]},{12'b0,addrin[63:12]},fetchedentry,tlbwraddr,tlbwr,reset,hit,hitentry);
pgfetcher fetcher(din,pl6pdata,addrin[63:12],memcycle,hit,reset,clk,pl6pwr,pgen,stopwalk,walkaddr,fetchedentry,tlbwr,pgstrctwalk,pgft);
assign addrout=(pgstrctwalk) ? walkaddr : {hitentry[63:12],addrin[11:0]};
assign width=2'h3;
always @ (posedge tlbwr or reset) begin
if (reset)
tlbwraddr<=0;
if (tlbwr & pgstrctwalk)
tlbwraddr<=tlbwraddr+1;
end
endmodule

19
verilog/lib/pc.sv Normal file
View File

@ -0,0 +1,19 @@
module pc (input clk,reset,jump,
input[63:0] jumpaddr,
output wire[63:0] retaddr,pc);
logic[63:0] pcreg=0;
assign pc=pcreg;
assign retaddr=pc+16;
always @ (posedge clk or reset or jump) begin
if(reset)
pcreg<=0;
else if(jump)
pcreg<=jumpaddr;
else if(clk)
pcreg<=pc+16;
end
endmodule

52
verilog/lib/pgfetcher.sv Normal file
View File

@ -0,0 +1,52 @@
module pgfetcher (input [63:0] din,pl6pdata,
input [51:0] pgnoin,
input memcycle,hit,reset,clk,pl6pwr,pgen,stopwalk,
output [63:0] walkaddr,
output logic [63:0] writeentry,
output tlbwr,
output logic pgstrctwalk,pgft);
logic [63:0] pl6p=0;
logic [63:0] fetchedentry=0;
logic [8:0] pgoffset;
logic [2:0] fetchphase;
logic pgstrctwalk_ff;
assign writeentry=din;
assign pgstrctwalk=((~hit || pgstrctwalk_ff) && pgen && memcycle && !stopwalk);
assign pgft=(din[0]==0 && pgstrctwalk);
assign walkaddr={((fetchphase==0) ? pl6p[63:12] : fetchedentry[63:12]),pgoffset,3'b0};
assign tlbwr=(fetchphase==6);
always @ ( posedge clk or hit or reset or posedge stopwalk) begin
if (hit || reset || stopwalk)
pgstrctwalk_ff<=0;
else if (memcycle && clk && pgen)
pgstrctwalk_ff<=1;
end
always @ ( * ) begin
case (fetchphase)
0: pgoffset=pgnoin[51:45];
1: pgoffset=pgnoin[44:36];
2: pgoffset=pgnoin[35:27];
3: pgoffset=pgnoin[26:18];
4: pgoffset=pgnoin[17:9];
5: pgoffset=pgnoin[8:0];
default: pgoffset=0;
endcase
end
always @ (posedge clk or reset or hit or pgstrctwalk_ff or posedge stopwalk) begin
if (hit || reset || stopwalk)
fetchphase<=0;
if(clk && pgstrctwalk_ff)
fetchphase<=fetchphase+1;
if(clk && pgstrctwalk_ff && ~tlbwr)
fetchedentry<=din;
if (clk && pl6pwr)
pl6p<=pl6pdata;
end
endmodule

73
verilog/lib/ram.sv Normal file
View File

@ -0,0 +1,73 @@
module ram (input[63:0] din,ain,
input[1:0] width,
input clk,write,
output wire[63:0] dout);
reg[63:0] ram[65536:0];
reg[63:0] wrdata;
reg[63:0] rddata;
wire[63:0] ramval;
assign ramval=ram[ain>>3];
assign dout=(write&&clk) ? din : rddata;
always @ ( * ) begin
case(width)
0: case(ain[2:0])
0: wrdata={ramval[63:8],din[7:0]};
1: wrdata={ramval[63:16],din[7:0],ramval[7:0]};
2: wrdata={ramval[63:24],din[7:0],ramval[15:0]};
3: wrdata={ramval[63:32],din[7:0],ramval[23:0]};
4: wrdata={ramval[63:40],din[7:0],ramval[31:0]};
5: wrdata={ramval[63:48],din[7:0],ramval[39:0]};
6: wrdata={ramval[63:56],din[7:0],ramval[47:0]};
7: wrdata={din[7:0],ramval[55:0]};
default: wrdata=0;
endcase
1: case(ain[2:1])
0: wrdata={ramval[63:16],din[15:0]};
1: wrdata={ramval[63:32],din[15:0],ramval[15:0]};
2: wrdata={ramval[63:48],din[15:0],ramval[31:0]};
3: wrdata={ramval[15:0],ramval[47:0]};
default: wrdata=0;
endcase
2: case(ain[2])
0: wrdata={ramval[63:32],din[31:0]};
1: wrdata={din[31:0],ramval[31:0]};
default: wrdata=0;
endcase
3: wrdata=din;
default: wrdata=0;
endcase
end
always @ (posedge clk or write) begin
if(write)
ram[ain>>3]<=wrdata;
end
always @ ( * ) begin
case(width)
0: case(ain[2:0])
0: rddata=ramval[7:0];
1: rddata=ramval[15:8];
2: rddata=ramval[23:16];
3: rddata=ramval[31:24];
4: rddata=ramval[39:32];
5: rddata=ramval[47:40];
6: rddata=ramval[55:48];
7: rddata=ramval[63:56];
default: rddata=0;
endcase
1: case(ain[2:1])
0: rddata=ramval[15:0];
1: rddata=ramval[31:16];
2: rddata=ramval[47:32];
3: rddata=ramval[63:48];
default: rddata=0;
endcase
2: case(ain[2])
0: rddata=ramval[31:0];
1: rddata=ramval[63:32];
default: rddata=0;
endcase
3: rddata=ramval;
endcase
end
endmodule // ram

31
verilog/lib/regfile.sv Executable file
View File

@ -0,0 +1,31 @@
module regfile (input[63:0] din,
input[1:0] width,
input reset,wr,
input[3:0] wrsel,rdasel,rdbsel,
output wire[63:0] rdaout,rdbout);
reg[63:0] regs[16];
always @ (wr or reset) begin
if(reset) begin
integer i;
for(i=0; i<16; i=i+1) begin
regs[i]<=0;
end
end;
if(wr) begin
if(width==0) begin
regs[wrsel]<=din&64'hFF;
end
if(width==1) begin
regs[wrsel]<=din&64'hFFFF;
end
if(width==2) begin
regs[wrsel]<=din&64'hFFFFFFFF;
end
if(width==3) begin
regs[wrsel]<=din;
end
end
end
assign rdaout=regs[rdasel];
assign rdbout=regs[rdbsel];
endmodule

25
verilog/lib/regfile_if.sv Normal file
View File

@ -0,0 +1,25 @@
module regfile_if (input[63:0] din,retaddr,imm,aluout,
input[1:0] width,
input reset,wr,retload,immload,aluload,setr,
input[3:0] wrsel,rdasel,rdbsel,
output wire[63:0] rdaout,rdbout);
logic[63:0] rf_din;
wire rf_wr;
regfile rf(rf_din,width,reset,rf_wr,wrsel,rdasel,rdbsel,rdaout,rdbout);
assign rf_wr=~(aluload&(~setr))&wr;
always @ ( din or retaddr or imm or aluout or retload or immload or aluload ) begin
if(aluload)
rf_din=aluout;
else if(immload)
rf_din=imm;
else if(retload)
rf_din=retaddr;
else
rf_din=din;
end
endmodule

181
verilog/lib/t64.sv Normal file
View File

@ -0,0 +1,181 @@
module t64 (input[63:0] din,
input clk,reset,intr,
output logic[63:0] aouttrue,
output wire[63:0] dout,
output wire[1:0] widthtrue,
output wire writetrue,
output reg intack,
output reg unhandledexcept);
wire[63:0] rdaout,rdbout,aluout,imm,retaddr,pc,aouttrans;
wire[7:0] aluop;
wire[3:0] wrsel,rdasel,rdbsel,inslen;
wire[1:0] width,walkwidth;
wire zero,carry,setr,regwr,retload,immload,aluload,jump,pointer,memaddr;
wire exec,pgstrctwalk,pgft,memcycle,specialwr,pl6pwr,intjumpaddrwr,iret;
wire intr_gated,exceptjumpaddrwr,write,except_jump,int_jump;
assign exec=(phase==2)&&!unhandledexcept&&!pendingexcept;
assign dout=rdbout;
assign writetrue=write&&!pgstrctwalk;
assign aouttrue=(pgen) ? aouttrans : aout;
assign widthtrue=(pgen&&pgstrctwalk) ? walkwidth : width;
assign memcycle=phase==0||phase==1||pointer||memaddr;
assign pl6pwr=(imm==0&specialwr);
assign intjumpaddrwr=(imm==1&specialwr);
assign exceptjumpaddrwr=(imm==2&specialwr);
assign intr_gated=intr&inten&!unhandledexcept;
reg[63:0] opf8,opl8,aout,intjumpaddr,exceptjumpaddr,exceptno,intretaddr;
reg[63:0] exceptretaddr,jumpaddr;
reg pgen=0;
reg inten=0;
reg excepten=0;
reg oldinten=0;
reg oldhandleint=0;
reg handleint=0;
reg handleexcept=0;
reg stopwalk=0;
reg pendingexcept=0;
assign except_jump=excepten && pendingexcept && phase==0;
assign int_jump=intr_gated && inten && phase==0;
control cntrl(opf8,opl8,exec,carry,zero,imm,aluop,wrsel,rdasel,rdbsel,width,retload,regwr,write,aluload,jump,immload,memaddr,pointer,specialwr,iret);
regfile_if rf(din,retaddr,imm,aluout,width,reset,regwr&&clk,retload,immload,aluload,setr,wrsel,rdasel,rdbsel,rdaout,rdbout);
alu_if alu(rdaout,rdbout,imm,aluop,width,clk,reset,immload,aluload&&exec,aluout,zero,carry,setr);
pc pgmc(clk&&exec&&!pgstrctwalk,reset,jump||iret||int_jump||except_jump,jumpaddr,retaddr,pc);
mmu memmu(aout,din,rdaout,reset,memcycle,clk,pl6pwr,pgen,stopwalk,aouttrans,walkwidth,pgstrctwalk,pgft);
logic[1:0] phase;
always @ ( * ) begin
if (jump)
jumpaddr=aout;
else if (iret&&handleexcept)
jumpaddr=exceptretaddr;
else if (iret&&handleint)
jumpaddr=intretaddr;
else if (pendingexcept||handleexcept)
jumpaddr=exceptjumpaddr;
else if (intr_gated)
jumpaddr=intjumpaddr;
else
jumpaddr=0;
end
always @ (posedge clk or reset or din) begin
if(reset) begin
phase<=0;
opf8<=0;
opl8<=0;
pgen<=0;
intjumpaddr<=0;
intack<=0;
inten<=0;
excepten<=0;
handleint<=0;
handleexcept<=0;
exceptjumpaddr<=0;
exceptno<=0;
oldinten<=0;
oldhandleint<=0;
unhandledexcept<=0;
stopwalk<=0;
pendingexcept<=0;
intretaddr<=0;
exceptretaddr<=0;
end
else if(clk) begin
if(phase==0)
opf8<=din;
else if(phase==1)
opl8<=din;
end
end
always @ (negedge clk) begin
if (!pgstrctwalk ||!pgen)
if(phase!=2&&!intr_gated) begin
phase<=phase+1;
if (phase==1)
intack<=0;
end
else begin
phase<=0;
if (pendingexcept)
if (excepten && !handleexcept) begin
handleexcept<=1;
excepten<=0;
oldinten<=inten;
inten<=0;
handleint<=0;
oldhandleint<=handleint;
pendingexcept<=0;
stopwalk<=0;
end
else
unhandledexcept<=1;
else if (intr_gated) begin
intretaddr<=retaddr;
intack<=1;
inten<=0;
handleint<=1;
end
end
end
always @ ( posedge clk ) begin
if(iret) begin
$display("IRET");
if(handleexcept) begin
$display("HANDLE EXCEPTION. RETADDR:0x%x",exceptretaddr);
handleexcept<=0;
excepten<=1;
inten<=oldinten;
handleint<=oldhandleint;
pgmc.pcreg<=exceptretaddr;
end
end
else if (handleint) begin
inten<=1;
handleint<=0;
pgmc.pcreg<=intretaddr;
end
end
always @ ( * ) begin
if(phase==0)
aout=pc;
else if(phase==1)
aout=pc+8;
else if(pointer==1)
aout=rdaout;
else if(memaddr==1)
aout=imm;
else
aout=0;
end
always @ ( posedge pl6pwr ) begin
pgen<=rdaout[0];
end
always @ ( posedge intjumpaddrwr ) begin
intjumpaddr<=rdaout&~64'h7;
inten<=rdaout[0];
excepten<=rdaout[0];
end
always @ ( posedge exceptjumpaddrwr ) begin
exceptjumpaddr<=rdaout&~64'h7;
end
always @ ( posedge clk ) begin
if (pgft==1) begin
// #5;
// $display("FAULT!! Before setting signals pgstrctwalk=%d pgft=%d stopwalk=%d aouttrue=0x%x aouttrans: 0x%x, aout: 0x%x, memmu.fetchedentry=0x%x din[0]=%d",pgstrctwalk,pgft,stopwalk,aouttrue,aouttrans,aout,memmu.fetchedentry,din[0]);
pendingexcept<=1;
exceptno<=0;
stopwalk<=1;
exceptretaddr<=pc;
// $display("FAULT!! After setting signals pgstrctwalk=%d pgft=%d stopwalk=%d aouttrue=0x%x aouttrans: 0x%x, aout: 0x%x, memmu.fetchedentry=0x%x din[0]=%d",pgstrctwalk,pgft,stopwalk,aouttrue,aouttrans,aout,memmu.fetchedentry,din[0]);
// #5;
// $finish();
end
end
endmodule

32
verilog/lib/tlb.sv Normal file
View File

@ -0,0 +1,32 @@
module tlb #(parameter length = 4096) (input [63:0] pageno,wrpageno,tableentry,
input [12:0] wraddr,
input write,
input reset,
output logic hit,
output logic[63:0] data);
logic[64:0] pgnos[length-1:0];
logic[64:0] entries[length-1:0];
integer i=0;
always @ (posedge write or reset) begin
if (reset) begin
for (i=0;i<length;i=i+1)
pgnos[i]=64'h0;
entries[i]=64'h0;
end
else if (write) begin
pgnos[wrpageno]=wrpageno;
entries[wrpageno]=tableentry;
end
end
always @ ( * ) begin
data=0;
hit=0;
for (i=0;i<length;i=i+1)
if ((pgnos[i]==pageno)&&entries[i][0]&&~hit) begin
data=entries[i];
hit=1;
end
end
endmodule

77
verilog/mmu_tb.sv Normal file
View File

@ -0,0 +1,77 @@
module mmu_tb ();
reg [63:0] addrin,din,pl6pdata;
reg reset,memcycle,clk,pl6pwr;
wire [63:0] addrout;
wire [1:0] width;
wire pgstrctwalk,pgft;
mmu DUT(
.addrin(addrin),
.din(din),
.pl6pdata(pl6pdata),
.reset(reset),
.memcycle(memcycle),
.clk(clk),
.pl6pwr(pl6pwr),
.addrout(addrout),
.width(width),
.pgstrctwalk(pgstrctwalk),
.pgft(pgft)
);
initial begin
$dumpfile("dumps/mmu.vcd");
$dumpvars(0,mmu_tb);
addrin=64'h0;
din=64'h0;
pl6pdata=64'h0;
reset=1'b0;
memcycle=1'b0;
clk=1'b0;
pl6pwr=1'b0;
#1;
reset=1'b1;
#1;
reset=1'b0;
pl6pdata=64'h1000;
pl6pwr=1'b1;
clk=1'b1;
#1;
clk=1'b0;
pl6pwr=1'b0;
#1;
din=64'h2001;
memcycle=1'b1;
clk=1'b1;
#1
clk=1'b0;
#1
din=64'h3000;
clk=1'b1;
#1
clk=1'b0;
#1
din=64'h4001;
clk=1'b1;
#1;
clk=1'b0;
#1;
din=64'h5001;
clk=1'b1;
#1;
clk=1'b0;
#1;
din=64'h6001;
clk=1'b1;
#1;
clk=1'b0;
#1;
din=64'ha001;
clk=1'b1;
#1;
clk=1'b0;
#1;
end
endmodule

20
verilog/opcodetrans.txt Normal file
View File

@ -0,0 +1,20 @@
00 LDB
01 LDW
02 LDDW
03 LD
04 STB
05 STW
06 STDW
07 ST
08 ARB
09 ARW
0a ARDW
0b AR
0c JMP
0d JZ
0e JNZ
0f JC
10 JNC
11 JST
12 LDSPECIAL
13 IRET

45
verilog/pc_tb.sv Normal file
View File

@ -0,0 +1,45 @@
module pc_tb();
logic clk,reset,jump;
logic[63:0] jumpaddr,retaddr,pc;
pc DUT (
.clk(clk),
.reset(reset),
.jump(jump),
.jumpaddr(jumpaddr),
.retaddr(retaddr),
.pc(pc)
);
initial begin
$dumpfile("dumps/pc.vcd");
$dumpvars(0,pc_tb);
clk=1'b0;
reset=1'b0;
jump=1'b0;
jumpaddr=64'h0;
#1;
reset=1'b1;
#1;
reset=1'b0;
#1
clk=1'b1;
#1;
clk=1'b0;
#1
clk=1'b1;
#1;
clk=1'b0;
jumpaddr=64'h60;
jump=1'b1;
#1;
clk=1'b1;
#1;
clk=1'b0;
reset=1'b1;
#1;
reset=1'b0;
end
endmodule

3
verilog/phasetrans.txt Normal file
View File

@ -0,0 +1,3 @@
00 FETCHL
01 FETCHH
10 EXEC

30
verilog/prog.hex Normal file
View File

@ -0,0 +1,30 @@
00000010c1000003
0000000000000000
0000000001000012
0000000000000000
00000010c1000003
0000000000000000
0000000002000012
0000000000000000
000000A001000003
0000000000000000
0000000000000012
0000000000000000
00000000b0001000
0000000000000000
0000000103008008
0000000000000000
00000000b0001004
0000000000000000
000000007000100e
0000000000000000
00000000000000FF
0000000000000000
0000000000000000
0000000000000000
0000000001000003
0000000000000000
000000F000001007
0000000000000000
0000000000000013
0000000000000000

0
verilog/ram_tb.sv Normal file
View File

8
verilog/ramtest.hex Normal file
View File

@ -0,0 +1,8 @@
0000000001000003
0000000000000000
000000F000001007
0000000000000000
000000F000001103
0000000000000000
00000000000000FF
0000000000000000

32
verilog/regfile_if_tb.sv Normal file
View File

@ -0,0 +1,32 @@
module regfile_if_tb();
logic[63:0] din,retaddr,imm,aluout,rdaout,rdbout;
logic[1:0] width;
logic reset,wr,retload,immload,aluload,setr;
logic[3:0] wrsel,rdasel,rdbsel;
regfile_if DUT (
.din(din),
.retaddr(retaddr),
.imm(imm),
.aluout(aluout),
.rdaout(rdaout),
.rdbout(rdbout),
.width(width),
.reset(reset),
.wr(wr),
.retload(retload),
.immload(immload),
.aluload(aluload),
.setr(setr),
.wrsel(wrsel),
.rdasel(rdasel),
.rdbsel(rdbsel)
);
initial begin
$dumpfile("dumps/regfile_if.vcd");
$dumpvars(0,regfile_if_tb);
end
endmodule

53
verilog/regfile_tb.sv Normal file
View File

@ -0,0 +1,53 @@
module regfile_tb();
logic [63:0] din,rdaout,rdbout;
logic [3:0] wrsel,rdasel,rdbsel;
logic [1:0] width;
logic reset,wr;
regfile DUT (
.din(din),
.rdaout(rdaout),
.rdbout(rdbout),
.wrsel(wrsel),
.rdasel(rdasel),
.rdbsel(rdbsel),
.reset(reset),
.wr(wr),
.width(width)
);
initial begin
$dumpfile("dumps/regfile.vcd");
$dumpvars(0,regfile_tb);
width=2'h0;
din=64'h0;
reset=1'b0;
wr=1'b0;
wrsel=4'h0;
rdasel=4'h0;
rdbsel=4'h0;
#1
width=2'h0;
din=64'h0;
reset=1'b1;
wr=1'b0;
wrsel=4'h0;
rdasel=4'h0;
rdbsel=4'h0;
#1
reset=1'b0;
#1
din=64'hFFFFFFFFFFFFFFFF;
wr=1'b1;
#1
wr=1'b0;
#1
reset=1'b1;
#1
reset=1'b0;
#1
$finish;
end
endmodule

92
verilog/t64.gtkw Normal file
View File

@ -0,0 +1,92 @@
[*]
[*] GTKWave Analyzer v3.3.103 (w)1999-2019 BSI
[*] Sat Jun 13 15:19:31 2020
[*]
[dumpfile] "/Users/peterterpstra/Desktop/projects/t64/verilog/dumps/t64.lxt"
[dumpfile_mtime] "Sat Jun 13 14:40:05 2020"
[dumpfile_size] 1604706
[savefile] "/Users/peterterpstra/Desktop/projects/t64/verilog/t64.gtkw"
[timestart] 0
[size] 1440 811
[pos] -106 -1
*-0.995732 13 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[treeopen] t64_system.
[treeopen] t64_system.CPU.
[sst_width] 193
[signals_width] 167
[sst_expanded] 1
[sst_vpaned_height] 241
@200
-Memory bus:
@22
t64_system.addr[63:0]
t64_system.dbus[63:0]
@2028
^5 /Users/peterterpstra/Desktop/projects/t64/verilog/widthtrans.txt
t64_system.width[1:0]
@200
-Control signals:
@28
t64_system.write
t64_system.clk
t64_system.reset
@200
-CPU state:
@22
t64_system.CPU.pc[63:0]
t64_system.insword[127:0]
@2028
^4 /Users/peterterpstra/Desktop/projects/t64/verilog/phasetrans.txt
t64_system.CPU.phase[1:0]
@28
t64_system.CPU.zero
@22
t64_system.CPU.rf.rf.\regs[0][63:0]
@200
-Decode signals:
@2028
^5 /Users/peterterpstra/Desktop/projects/t64/verilog/widthtrans.txt
t64_system.CPU.cntrl.opwidth[1:0]
@c02022
^3 /Users/peterterpstra/Desktop/projects/t64/verilog/opcodetrans.txt
t64_system.CPU.cntrl.opcode[7:0]
@28
(0)t64_system.CPU.cntrl.opcode[7:0]
(1)t64_system.CPU.cntrl.opcode[7:0]
(2)t64_system.CPU.cntrl.opcode[7:0]
(3)t64_system.CPU.cntrl.opcode[7:0]
(4)t64_system.CPU.cntrl.opcode[7:0]
(5)t64_system.CPU.cntrl.opcode[7:0]
(6)t64_system.CPU.cntrl.opcode[7:0]
(7)t64_system.CPU.cntrl.opcode[7:0]
@1401200
-group_end
@2022
^1 /Users/peterterpstra/Desktop/projects/t64/verilog/addrtrans.txt
t64_system.CPU.cntrl.addrmode[3:0]
@22
t64_system.CPU.cntrl.rdasel[3:0]
t64_system.CPU.cntrl.rdbsel[3:0]
t64_system.CPU.cntrl.wrsel[3:0]
@2022
^2 /Users/peterterpstra/Desktop/projects/t64/verilog/aluoptrans.txt
t64_system.CPU.cntrl.aluop[7:0]
@22
t64_system.CPU.cntrl.imm[63:0]
@28
t64_system.CPU.cntrl.immload
t64_system.CPU.cntrl.aluload
@29
t64_system.CPU.cntrl.pcload
@28
t64_system.CPU.cntrl.memaddr
t64_system.CPU.cntrl.pointer
t64_system.CPU.cntrl.regwrop
t64_system.CPU.cntrl.memwrop
t64_system.CPU.cntrl.jumpop
@200
-Memory:
@22
t64_system.RAM.\ram[10][63:0]
[pattern_trace] 1
[pattern_trace] 0

74
verilog/t64_system.sv Normal file
View File

@ -0,0 +1,74 @@
module t64_system ();
logic [63:0] din,addr,dout;
logic [1:0] width;
logic clk,reset,write,intr,intack,unhandledexcept;
integer i;
ram RAM (
.din(dout),
.dout(din),
.ain(addr),
.width(width),
.write(write),
.clk(clk)
);
t64 CPU (
.din(din),
.clk(clk),
.reset(reset),
.intr(intr),
.aouttrue(addr),
.dout(dout),
.widthtrue(width),
.writetrue(write),
.intack(intack),
.unhandledexcept(unhandledexcept)
);
wire[127:0] insword;
assign insword={CPU.opl8,CPU.opf8};
wire[63:0] dbus;
assign dbus=(write) ? dout : din;
initial begin
$dumpfile("dumps/t64.lxt");
$dumpvars(10,RAM,CPU,t64_system,RAM.ram[22]);
for (i=0;i<16;i=i+1) begin
$dumpvars(0,CPU.rf.rf.regs[i]);
end
for (i=0;i<65536;i=i+1) begin
RAM.ram[i]=0;
end
$readmemh("prog.hex",RAM.ram);
RAM.ram[16'hA000>>3]=64'hB001;
RAM.ram[16'hB000>>3]=64'hC001;
RAM.ram[16'hC000>>3]=64'hD001;
RAM.ram[16'hD000>>3]=64'hE001;
RAM.ram[16'hE000>>3]=64'hF001;
RAM.ram[16'hF000>>3]=64'h0000;
RAM.ram[16'hF008>>3]=64'h0001;
RAM.ram[16'hF078>>3]=64'hF001;
// CPU.memmu.fetcher.pl6p=64'hA000;
intr=1'b0; clk=1'b0; reset=1'b1; #1;
reset=1'b0;
// repeat(32) begin
// clk=1'b1; #1;
// clk=1'b0; #1;
// if(RAM.ram[CPU.pc>>3]==64'hFF)
// $finish;
// end
// end
// intr=1'b1;
forever begin
clk=1'b1; #1;
clk=1'b0; #1;
if((CPU.phase==0 && din==64'hFF) || unhandledexcept) begin
$finish;
end
if(intack) begin
intr=1'b0;
end
end
end
endmodule

49
verilog/tlb_tb.sv Normal file
View File

@ -0,0 +1,49 @@
module tlb_tb ();
logic [63:0] pageno,wrpageno,tableentry,data;
logic [12:0] wraddr;
logic write,hit,reset;
tlb DUT (
.pageno(pageno),
.wrpageno(wrpageno),
.tableentry(tableentry),
.wraddr(wraddr),
.write(write),
.reset(reset),
.hit(hit),
.data(data)
);
initial begin
$dumpfile("dumps/tlb.lxt");
$dumpvars(0,tlb_tb);
pageno=64'h0;
wrpageno=64'h0;
tableentry=64'h0;
wraddr=12'h0;
write=1'b0;
reset=1'b0;
#1;
reset=1'b1;
#1
reset=1'b0;
write=1'b1;
#1;
write=1'b0;
tableentry=64'h5001;
#1;
write=1'b1;
#1;
write=1'b0;
#1;
pageno=64'h1;
#1;
wrpageno=64'h1;
wraddr=12'h1;
tableentry=64'h6001;
write=1'b1;
#1;
write=1'b0;
#1;
end
endmodule

4
verilog/widthtrans.txt Normal file
View File

@ -0,0 +1,4 @@
00 8BIT
01 16BIT
10 32BIT
11 64BIT