Initial Commit
This commit is contained in:
commit
632317095f
16
PPCI Config space layout.txt
Normal file
16
PPCI Config space layout.txt
Normal 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)
|
75
asm.rb
Normal file
75
asm.rb
Normal 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
|
220
c_compiler/backend/backend.rb
Normal file
220
c_compiler/backend/backend.rb
Normal 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
28
c_compiler/compiler.rb
Normal 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
93
c_compiler/file
Normal 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
55
c_compiler/frontend/c.rex
Normal 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
91
c_compiler/frontend/c.y
Normal 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
|
256
c_compiler/frontend/frontend.rb
Normal file
256
c_compiler/frontend/frontend.rb
Normal 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
|
184
c_compiler/frontend/lexer.rb
Normal file
184
c_compiler/frontend/lexer.rb
Normal 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
|
1023
c_compiler/frontend/parser.output
Normal file
1023
c_compiler/frontend/parser.output
Normal file
File diff suppressed because it is too large
Load Diff
542
c_compiler/frontend/parser.rb
Normal file
542
c_compiler/frontend/parser.rb
Normal 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
55
c_compiler/ir.rex
Normal 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
51
c_compiler/ir.y
Normal 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
|
28
c_compiler/middleend/constprop.rb
Normal file
28
c_compiler/middleend/constprop.rb
Normal 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
|
41
c_compiler/middleend/deadcode.rb
Normal file
41
c_compiler/middleend/deadcode.rb
Normal 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
|
10
c_compiler/middleend/middleend.rb
Normal file
10
c_compiler/middleend/middleend.rb
Normal 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
|
69
c_compiler/middleend/ssa.rb
Normal file
69
c_compiler/middleend/ssa.rb
Normal 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
22
c_compiler/rom.c
Normal 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
261
c_compiler/rom.ir
Normal 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
57
c_compiler/rom.t64
Normal 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
259
lexer.rb
Normal 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
3
maskrom
Normal 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
591
parser.rb
Normal 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
2
progs/call.bin
Normal 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
16
progs/call.lst
Normal 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
13
progs/call.t64
Normal 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
2
progs/inc.bin
Normal 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
14
progs/inc.lst
Normal 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
8
progs/inc.t64
Normal 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
2
progs/inc2.bin
Normal 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
11
progs/inc2.hex
Normal file
@ -0,0 +1,11 @@
|
||||
0000000050001000
|
||||
0000000000000000
|
||||
0000000103008008
|
||||
0000000000000000
|
||||
0000000050001004
|
||||
0000000000000000
|
||||
000000000000100e
|
||||
0000000000000000
|
||||
00000000000000ff
|
||||
0000000000000000
|
||||
0000000000000000
|
9
progs/inc2.lst
Normal file
9
progs/inc2.lst
Normal 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
6
progs/inc2.t64
Normal 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
20
progs/incwpaging.t64
Normal 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
2
progs/pgtest.bin
Normal 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
11
progs/pgtest.lst
Normal 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
8
progs/pgtest.t64
Normal 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
4097
progs/pgtestfixedwtables.bin
Normal file
File diff suppressed because it is too large
Load Diff
2
progs/rom.bin
Normal file
2
progs/rom.bin
Normal 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
24
progs/rom.lst
Normal 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
16
progs/rom.t64
Normal 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
80
t64.rex
Normal 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
92
t64.y
Normal 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
13
verilog/Makefile
Normal 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
10
verilog/addrtrans.txt
Normal 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
0
verilog/alu_if_tb.sv
Normal file
37
verilog/alu_tb.sv
Normal file
37
verilog/alu_tb.sv
Normal 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
256
verilog/aluoptrans.txt
Normal 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
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
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
BIN
verilog/dumps/mmu.vcd
Normal file
Binary file not shown.
BIN
verilog/dumps/t64.lxt
Normal file
BIN
verilog/dumps/t64.lxt
Normal file
Binary file not shown.
BIN
verilog/dumps/tlb.lxt
Normal file
BIN
verilog/dumps/tlb.lxt
Normal file
Binary file not shown.
BIN
verilog/dumps/tlb4096.fst
Normal file
BIN
verilog/dumps/tlb4096.fst
Normal file
Binary file not shown.
110
verilog/lib/alu.sv
Normal file
110
verilog/lib/alu.sv
Normal 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
30
verilog/lib/alu_if.sv
Normal 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
101
verilog/lib/control.sv
Normal 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
26
verilog/lib/mmu.sv
Normal 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
19
verilog/lib/pc.sv
Normal 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
52
verilog/lib/pgfetcher.sv
Normal 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
73
verilog/lib/ram.sv
Normal 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
31
verilog/lib/regfile.sv
Executable 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
25
verilog/lib/regfile_if.sv
Normal 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))≀
|
||||
|
||||
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
181
verilog/lib/t64.sv
Normal 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
32
verilog/lib/tlb.sv
Normal 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
77
verilog/mmu_tb.sv
Normal 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
20
verilog/opcodetrans.txt
Normal 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
45
verilog/pc_tb.sv
Normal 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
3
verilog/phasetrans.txt
Normal file
@ -0,0 +1,3 @@
|
||||
00 FETCHL
|
||||
01 FETCHH
|
||||
10 EXEC
|
30
verilog/prog.hex
Normal file
30
verilog/prog.hex
Normal 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
0
verilog/ram_tb.sv
Normal file
8
verilog/ramtest.hex
Normal file
8
verilog/ramtest.hex
Normal file
@ -0,0 +1,8 @@
|
||||
0000000001000003
|
||||
0000000000000000
|
||||
000000F000001007
|
||||
0000000000000000
|
||||
000000F000001103
|
||||
0000000000000000
|
||||
00000000000000FF
|
||||
0000000000000000
|
32
verilog/regfile_if_tb.sv
Normal file
32
verilog/regfile_if_tb.sv
Normal 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
53
verilog/regfile_tb.sv
Normal 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
92
verilog/t64.gtkw
Normal 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
74
verilog/t64_system.sv
Normal 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
49
verilog/tlb_tb.sv
Normal 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
4
verilog/widthtrans.txt
Normal file
@ -0,0 +1,4 @@
|
||||
00 8BIT
|
||||
01 16BIT
|
||||
10 32BIT
|
||||
11 64BIT
|
Loading…
x
Reference in New Issue
Block a user