From 4741ed8e14ebea48b25b8bf3b20dbacebaffac3d Mon Sep 17 00:00:00 2001 From: David Given Date: Sat, 1 Sep 2018 19:35:31 +0200 Subject: [PATCH] Add a completely non-tested table-based MIPS assembler. --- build.lua | 1 + h/out.h | 3 +- mach/mips/as/build.lua | 6 + mach/mips/as/instructions.dat | 152 +++++++++++++++++++++++++ mach/mips/as/mach0.c | 31 +++++ mach/mips/as/mach1.c | 12 ++ mach/mips/as/mach2.c | 12 ++ mach/mips/as/mach3.c | 84 ++++++++++++++ mach/mips/as/mach4.c | 88 +++++++++++++++ mach/mips/as/mach5.c | 0 mach/mips/as/mktables.lua | 188 +++++++++++++++++++++++++++++++ mach/proto/as/build.lua | 7 +- mach/proto/as/comm0.h | 1 + plat/linuxmips/build-pkg.lua | 25 ++++ plat/linuxmips/build-tools.lua | 30 +++++ plat/linuxmips/descr | 87 ++++++++++++++ plat/linuxmips/include/build.lua | 4 + 17 files changed, 728 insertions(+), 3 deletions(-) create mode 100644 mach/mips/as/build.lua create mode 100644 mach/mips/as/instructions.dat create mode 100644 mach/mips/as/mach0.c create mode 100644 mach/mips/as/mach1.c create mode 100644 mach/mips/as/mach2.c create mode 100644 mach/mips/as/mach3.c create mode 100644 mach/mips/as/mach4.c create mode 100644 mach/mips/as/mach5.c create mode 100755 mach/mips/as/mktables.lua create mode 100644 plat/linuxmips/build-pkg.lua create mode 100644 plat/linuxmips/build-tools.lua create mode 100644 plat/linuxmips/descr create mode 100644 plat/linuxmips/include/build.lua diff --git a/build.lua b/build.lua index 9bce99f90..df51d0d13 100644 --- a/build.lua +++ b/build.lua @@ -10,6 +10,7 @@ vars.plats = { "linux386", "linux68k", "linuxppc", + "linuxmips", "osx386", "osxppc", -- --"qemuppc", diff --git a/h/out.h b/h/out.h index 9cc791ab2..17a4c908c 100644 --- a/h/out.h +++ b/h/out.h @@ -67,7 +67,8 @@ struct outname { #define RELO4 3 /* 4 bytes */ #define RELOPPC 4 /* PowerPC 26-bit address */ #define RELOPPC_LIS 5 /* PowerPC lis */ -#define RELOVC4 6 /* VideoCore IV address in 32-bit instruction */ +#define RELOVC4 6 /* VideoCore IV address in 32-bit instruction */ +#define RELOMIPS 7 /* MIPS */ #define RELPC 0x2000 /* pc relative */ #define RELBR 0x4000 /* High order byte lowest address. */ diff --git a/mach/mips/as/build.lua b/mach/mips/as/build.lua new file mode 100644 index 000000000..8732fdf14 --- /dev/null +++ b/mach/mips/as/build.lua @@ -0,0 +1,6 @@ +normalrule { + name = "astables", + outleaves = {"definitions.y", "tokens.y", "rules.y"}, + ins = {"./mktables.lua", "./instructions.dat"}, + commands = {"$(LUA) %{ins[1]} %{outs} < %{ins[2]}"} +} diff --git a/mach/mips/as/instructions.dat b/mach/mips/as/instructions.dat new file mode 100644 index 000000000..af5209e5b --- /dev/null +++ b/mach/mips/as/instructions.dat @@ -0,0 +1,152 @@ +# Syntax: +# : a field occupying so many bits. +# T: a field occupying one bit. +# Undefined bits end up as 0. +# +# This is intended to be compatible with MIPS release 5, integer instructions +# only. It's based on the MIPS32 Instruction Set v5.04 manual (available from +# https://www.mips.com/products/architectures/mips32-2/). + +00000000000100000 "add" RD=gpr ',' RS=gpr ',' RT=gpr +001000 "addi" RT=gpr ',' RT=gpr ',' IMM=e16 +001001 "addiu" RT=gpr ',' RT=gpr ',' IMM=e16 +00000000000100001 "addu" RD=gpr ',' RS=gpr ',' RT=gpr +00000000000100100 "and" RD=gpr ',' RS=gpr ',' RT=gpr +001100 "andi" RT=gpr ',' RS=gpr ',' IMM=e16 +0001000000000000 "b" OFF=offset16 +0000010000010001 "bal" OFF=offset16 +000100 "beq" RS=gpr ',' RT=gpr ',' OFF=offset16 +010100 "beql" RS=gpr ',' RT=gpr ',' OFF=offset16 +00000100001 "bgez" RS=gpr ',' OFF=offset16 +00000110001 "bgezal" RS=gpr ',' OFF=offset16 +00000110011 "bgezall" RS=gpr ',' OFF=offset16 +00000100011 "bgezl" RS=gpr ',' OFF=offset16 +00011100000 "bgtz" RS=gpr ',' OFF=offset16 +01011100000 "bgtzl" RS=gpr ',' OFF=offset16 +00011000000 "blez" RS=gpr ',' OFF=offset16 +01011000000 "blezl" RS=gpr ',' OFF=offset16 +00000100000 "bltz" RS=gpr ',' OFF=offset16 +00000110000 "bltzal" RS=gpr ',' OFF=offset16 +00000110010 "bltzall" RS=gpr ',' OFF=offset16 +00000100010 "bltzl" RS=gpr ',' OFF=offset16 +000101 "bne" RS=gpr ',' RT=gpr ',' OFF=offset16 +010101 "bnel" RS=gpr ',' RT=gpr ',' OFF=offset16 +101111 "cache" OP=u5 ',' OFF=e16 '(' RS=gpr ')' +0111110011011 "cachee" OP=u5 ',' OFF=e9 '(' RS=gpr ')' +01110000000100001 "clo" RD=RT=gpr ',' RS=gpr +01110000000100000 "clz" RD=RT=gpr ',' RS=gpr +01000010000000000000000000011111 "deret" +010000010110110000000000000 "di" RT=gpr +01000001011000000110000000000000 "di" +0000000000000000011010 "div" RS=gpr ',' RT=gpr +0000000000000000011011 "divu" RS=gpr ',' RT=gpr +00000000000000000000000011000000 "ehb" +010000010110110000000100000 "ei" RT=gpr +01000001011000000110000000100000 "ei" +011111000000 "ext" RT=gpr ',' RS=gpr ',' extmsblsb +011111000100 "ins" RT=gpr ',' RS=gpr ',' insmsblsb +000010 "j" ABS=abs26 +000011 "jal" ABS=abs26 +0000000000000000001001 "jalr" RD=gpr ',' RS=gpr +000000000001111100000001001 "jalr" RS=gpr +0000000000010000001001 "jalr.hb" RD=gpr ',' RS=gpr +000000000001111110000001001 "jalr.hb" RS=gpr +011101 "jalx" ABS=abs26 +000000000000000000000001000 "jr" RS=gpr +000000000000000010000001000 "jr.hb" RS=gpr +100000 "lb" RT=gpr ',' IMM=e16 '(' RS=gpr ')' +0111110101100 "lbe" RT=gpr ',' IMM=e9 '(' RS=gpr ')' +100100 "lbu" RT=gpr ',' IMM=e16 '(' RS=gpr ')' +0111110101000 "lbue" RT=gpr ',' IMM=e9 '(' RS=gpr ')' +100001 "lh" RT=gpr ',' IMM=e16 '(' RS=gpr ')' +0111110101101 "lhe" RT=gpr ',' IMM=e9 '(' RS=gpr ')' +100101 "lhu" RT=gpr ',' IMM=e16 '(' RS=gpr ')' +0111110101001 "lhue" RT=gpr ',' IMM=e9 '(' RS=gpr ')' +110000 "ll" RT=gpr ',' IMM=e16 '(' RS=gpr ')' +0111110101110 "lle" RT=gpr ',' IMM=e9 '(' RS=gpr ')' +00111100000 "lui" RT=gpr ',' IMM=e16 +100011 "lw" RT=gpr ',' IMM=e16 '(' RS=gpr ')' +0111110101111 "lwe" RT=gpr ',' IMM=e9 '(' RS=gpr ')' +100010 "lwl" RT=gpr ',' IMM=e16 '(' RS=gpr ')' +0111110011001 "lwle" RT=gpr ',' IMM=e9 '(' RS=gpr ')' +100110 "lwr" RT=gpr ',' IMM=e16 '(' RS=gpr ')' +0111110011010 "lwre" RT=gpr ',' IMM=e9 '(' RS=gpr ')' +0111000000000000000000 "madd" RS=gpr ',' RT=gpr +0111000000000000000001 "maddu" RS=gpr ',' RT=gpr +000000000000000000000010000 "mfhi" RD=gpr +000000000000000000000010010 "mflo" RD=gpr +00000000000001011 "movn" RD=gpr ',' RS=gpr ',' RT=gpr +00000000000001010 "movz" RD=gpr ',' RS=gpr ',' RT=gpr +0111000000000000000100 "msub" RS=gpr ',' RT=gpr +0111000000000000000101 "msubu" RS=gpr ',' RT=gpr +000000000000000000000010001 "mthi" RS=gpr +000000000000000000000010011 "mtlo" RS=gpr +01110000000000010 "mul" RD=gpr ',' RS=gpr ',' RT=gpr +0000000000000000011000 "mult" RS=gpr ',' RT=gpr +0000000000000000000001 "multu" RS=gpr ',' RT=gpr +00000000000000000000000000000000 "nop" +00000000000100111 "nor" RD=gpr ',' RS=gpr ',' RT=gpr +00000000000100101 "or" RD=gpr ',' RS=gpr ',' RT=gpr +001101 "ori" RS=gpr ',' RT=gpr +00000000000000000000000101000000 "pause" +110011 "pref" H=u5 ',' IMM=e16 '(' RS=gpr ')' +0111110100011 "prefe" H=u5 ',' IMM=e9 '(' RS=gpr ')' +01001100000001111 "prefx" H=u5 ',' RT=gpr '(' RS=gpr ')' +0111110000000000111011 "rdhwr" RT=gpr ',' RD=gpr +0100000101000000000000 "rdpgpr" RD=gpr ',' RT=gpr +00000000001000010 "rotr" RD=gpr ',' RT=gpr ',' SA=u5 +00000000001000110 "rotrv" RD=gpr ',' RT=gpr ',' RS=gpr +101000 "sb" RT=gpr ',' IMM=e16 '(' RS=gpr ')' +0111110011100 "sbe" RT=gpr ',' IMM=e9 '(' RS=gpr ')' +111000 "sc" RT=gpr ',' IMM=e16 '(' RS=gpr ')' +0111110011110 "sce" RT=gpr ',' IMM=e9 '(' RS=gpr ')' +011100111111 "sdbbp" CODE=u20 +0111110000010000100000 "seb" RD=gpr ',' RT=gpr +0111110000011000100000 "seh" RD=gpr ',' RT=gpr +101001 "sh" RT=gpr ',' IMM=e16 '(' RS=gpr ')' +0111110011101 "she" RT=gpr ',' IMM=e9 '(' RS=gpr ')' +00000000000000000 "sll" RD=gpr ',' RT=gpr ',' SA=u5 +00000000000000100 "sllv" RD=gpr ',' RT=gpr ',' RS=gpr +00000000000101010 "slt" RD=gpr ',' RS=gpr ',' RT=gpr +001010 "slti" RT=gpr ',' RS=gpr ',' IMM=e16 +001011 "sltiu" RT=gpr ',' RS=gpr ',' IMM=e16 +00000000000101011 "sltu" RD=gpr ',' RS=gpr ',' RT=gpr +00000000000000011 "sra" RD=gpr ',' RT=gpr ',' SA=u5 +00000000000000111 "srav" RD=gpr ',' RT=gpr ',' RS=gpr +00000000000000010 "srl" RD=gpr ',' RT=gpr ',' SA=u5 +00000000000000110 "srlv" RD=gpr ',' RT=gpr ',' RS=gpr +00000000000000000000000001000000 "ssnop" +00000000000100010 "sub" RD=gpr ',' RS=gpr ',' RT=gpr +00000000000100011 "subu" RD=gpr ',' RS=gpr ',' RT=gpr +101011 "sw" RT=gpr ',' IMM=e16 '(' RS=gpr ')' +0111110011111 "swe" RT=gpr ',' IMM=e9 '(' RS=gpr ')' +101010 "swl" RT=gpr ',' IMM=e16 '(' RS=gpr ')' +0111110010001 "swle" RT=gpr ',' IMM=e9 '(' RS=gpr ')' +101110 "swr" RT=gpr ',' IMM=e16 '(' RS=gpr ')' +0111110100010 "swre" RT=gpr ',' IMM=e9 '(' RS=gpr ')' +00000111111 "synci" IMM=e16 '(' RS=gpr ')' +000000001100 "syscall" CODE=u20 +0000000000000000110100 "teq" RS=gpr ',' RT=gpr +00000101100 "teqi" RS=gpr ',' IMM=e16 +0000000000000000110000 "tge" RS=gpr ',' RT=gpr +00000101000 "tgei" RS=gpr ',' IMM=e16 +00000101001 "tgeiu" RS=gpr ',' IMM=e16 +0000000000000000110001 "tgeu" RS=gpr ',' RT=gpr +01000010000000000000000000000011 "tlbinv" +01000010000000000000000000000100 "tlbinvf" +01000010000000000000000000001000 "tlbp" +01000010000000000000000000000001 "tlbr" +01000010000000000000000000000010 "tlbwi" +01000010000000000000000000000110 "tlbwr" +0000000000000000110010 "tlt" RS=gpr ',' RT=gpr +00000101010 "tlti" RS=gpr ',' IMM=e16 +00000101011 "tltiu" RS=gpr ',' IMM=e16 +0000000000000000110011 "tltu" RS=gpr ',' RT=gpr +0000000000000000110110 "tne" RS=gpr ',' RT=gpr +00000101110 "tnei" RS=gpr ',' IMM=e16 +01000010000000000000000000100000 "wait" +0100000111000000000000 "wrpgpr" RD=gpr ',' RT=gpr +0111110000000010100000 "wsbh" RD=gpr ',' RT=gpr +00000000000100110 "xor" RD=gpr ',' RS=gpr ',' RT=gpr +001110 "xori" RT=gpr ',' RS=gpr ',' IMM=e16 + diff --git a/mach/mips/as/mach0.c b/mach/mips/as/mach0.c new file mode 100644 index 000000000..f390bccf5 --- /dev/null +++ b/mach/mips/as/mach0.c @@ -0,0 +1,31 @@ +/* + * $Source$ + * $State$ + */ + +#define THREE_PASS /* branch and offset optimization */ +#define BYTES_REVERSED /* high order byte has lowest address */ +#define WORDS_REVERSED /* high order word has lowest address */ +#define LISTING /* enable listing facilities */ +#define RELOCATION /* generate relocatable code */ +#define DEBUG 0 + +#undef valu_t +#define valu_t int32_t + +#undef ADDR_T +#define ADDR_T uint32_t + +#undef word_t +#define word_t uint32_t + +#undef ALIGNWORD +#define ALIGNWORD 4 + +#undef ALIGNSECT +#define ALIGNSECT 4 + +#undef VALWIDTH +#define VALWIDTH 8 + +#define FIXUPFLAGS (RELBR | RELWR) diff --git a/mach/mips/as/mach1.c b/mach/mips/as/mach1.c new file mode 100644 index 000000000..50f799684 --- /dev/null +++ b/mach/mips/as/mach1.c @@ -0,0 +1,12 @@ +/* + * $Source$ + * $State$ + */ + +/* + * Do not #include anything here. Do it in mach/proto/as/comm0.h + */ + +void no_hl(void); +word_t eval_hl(struct expr_t* expr, int token); +void emit_hl(word_t in); diff --git a/mach/mips/as/mach2.c b/mach/mips/as/mach2.c new file mode 100644 index 000000000..2672c0b9a --- /dev/null +++ b/mach/mips/as/mach2.c @@ -0,0 +1,12 @@ +%token GPR +%token FPR + +%type gpr +%type e16 e9 +%type u20 u5 +%type abs26 offset16 + +%type extmsblsb insmsblsb + +#include "definitions.y" + diff --git a/mach/mips/as/mach3.c b/mach/mips/as/mach3.c new file mode 100644 index 000000000..d6da5e016 --- /dev/null +++ b/mach/mips/as/mach3.c @@ -0,0 +1,84 @@ +/* + * $Source$ + * $State$ + */ + +/* Integer registers */ + +0, GPR, 0, "$0", +0, GPR, 0, "$zero", +0, GPR, 1, "$1", +0, GPR, 1, "$at", +0, GPR, 2, "$2", +0, GPR, 3, "$3", +0, GPR, 4, "$4", +0, GPR, 5, "$5", +0, GPR, 6, "$6", +0, GPR, 7, "$7", +0, GPR, 8, "$8", +0, GPR, 9, "$9", +0, GPR, 10, "$10", +0, GPR, 11, "$11", +0, GPR, 12, "$12", +0, GPR, 13, "$13", +0, GPR, 14, "$14", +0, GPR, 15, "$15", +0, GPR, 16, "$16", +0, GPR, 17, "$17", +0, GPR, 18, "$18", +0, GPR, 19, "$19", +0, GPR, 20, "$20", +0, GPR, 21, "$21", +0, GPR, 22, "$22", +0, GPR, 23, "$23", +0, GPR, 24, "$24", +0, GPR, 25, "$25", +0, GPR, 26, "$26", +0, GPR, 27, "$27", +0, GPR, 28, "$28", +0, GPR, 28, "$gp", +0, GPR, 29, "$29", +0, GPR, 29, "$sp", +0, GPR, 30, "$30", +0, GPR, 30, "$fp", +0, GPR, 31, "$31", +0, GPR, 31, "$a", + +/* Floating-point registers */ + +0, FPR, 0, "$f0", +0, FPR, 1, "$f1", +0, FPR, 2, "$f2", +0, FPR, 3, "$f3", +0, FPR, 4, "$f4", +0, FPR, 5, "$f5", +0, FPR, 6, "$f6", +0, FPR, 7, "$f7", +0, FPR, 8, "$f8", +0, FPR, 9, "$f9", +0, FPR, 10, "$f10", +0, FPR, 11, "$f11", +0, FPR, 12, "$f12", +0, FPR, 13, "$f13", +0, FPR, 14, "$f14", +0, FPR, 15, "$f15", +0, FPR, 16, "$f16", +0, FPR, 17, "$f17", +0, FPR, 18, "$f18", +0, FPR, 19, "$f19", +0, FPR, 20, "$f20", +0, FPR, 21, "$f21", +0, FPR, 22, "$f22", +0, FPR, 23, "$f23", +0, FPR, 24, "$f24", +0, FPR, 25, "$f25", +0, FPR, 26, "$f26", +0, FPR, 27, "$f27", +0, FPR, 28, "$f28", +0, FPR, 29, "$f29", +0, FPR, 30, "$f30", +0, FPR, 31, "$f31", + +#include "tokens.y" + + diff --git a/mach/mips/as/mach4.c b/mach/mips/as/mach4.c new file mode 100644 index 000000000..2185fb245 --- /dev/null +++ b/mach/mips/as/mach4.c @@ -0,0 +1,88 @@ +#include "rules.y" + +gpr: GPR + +e16 + : absexp + { + /* Allow signed or unsigned 16-bit values. */ + if (($1 < -0x8000) || ($1 > 0xffff)) + serror("16-bit signed value out of range"); + $$ = (uint16_t) $1; + } + ; + +e9 + : absexp + { + /* Allow signed or unsigned 9-bit values. */ + if (($1 < -0x100) || ($1 > 0x1ff)) + serror("9-bit signed value out of range"); + $$ = (uint16_t) $1; + } + ; + +u20 + : absexp + { + if (($1 < 0) || ($1 > 0xfffff)) + serror("20-bit unsigned value out of range"); + $$ = $1; + } + ; + + +u5 + : absexp + { + if (($1 < 0) || ($1 > 0x1f)) + serror("5-bit unsigned value out of range"); + $$ = $1; + } + ; + +offset16 + : expr + { + int dist = $1.val - DOTVAL; + fit(fitx(dist, 18)); + + if (dist & 0x3) + serror("jump targets must be 4-aligned"); + + newrelo($1.typ, RELOMIPS | RELPC | FIXUPFLAGS); + $$ = (dist >> 2) & 0x0000ffff; + } + ; + +abs26 + : expr + { + int target = $1.val; + fit(fitx(target, 28)); + + if (target & 0x3) + serror("jump targets must be 4-aligned"); + + newrelo($1.typ, RELOMIPS | FIXUPFLAGS); + $$ = (target >> 2) & 0x03fffffd; + } + ; + +extmsblsb + : u5 ',' u5 + { + int pos = $1; + int size = $3; + $$ = ((size-1) << 5) | pos; + } + ; + +insmsblsb + : u5 ',' u5 + { + int pos = $1; + int size = $3; + $$ = ((pos+size-1) << 5) | pos; + } + ; \ No newline at end of file diff --git a/mach/mips/as/mach5.c b/mach/mips/as/mach5.c new file mode 100644 index 000000000..e69de29bb diff --git a/mach/mips/as/mktables.lua b/mach/mips/as/mktables.lua new file mode 100755 index 000000000..cb8565fc4 --- /dev/null +++ b/mach/mips/as/mktables.lua @@ -0,0 +1,188 @@ +local args = {...} + +local wordscount = 0 +local words = {} +local insns = {} + +local function addword(word) + local n = words[word] + if not n then + words[word] = wordscount + wordscount = wordscount + 1 + n = wordscount + end + return n +end + +local function parsesyntax(line) + local syntax = {} + for word in line:gmatch("%S+") do + local _, _, s = word:find('^"(.*)"$') + if s then + syntax[#syntax+1] = {word=addword(s) } + else + _, _, s = word:find("^('.*')$") + if s then + syntax[#syntax+1] = {punct=s } + else + local token = {} + for equate in word:gmatch("([^=]+)=") do + token[#token+1] = equate + end + _, _, token.token = word:find("([^=]*)$") + syntax[#syntax+1] = token + if not token.token then + error("can't parse "..word) + end + end + end + end + return syntax +end + +local function parsefields(line) + local _, _, bits = line:find("^([^ ]+) ") + if #bits ~= 32 then + error("'"..bits.."' isn't 32 bits long") + end + + local fields = {} + local i = 1 + while i ~= 33 do + local c = line:sub(i, i) + if c ~= "." then + local f = { pos=i } + if c:find("%w") then + f.size = 1 + f.value = c + elseif c == "<" then + local _, newi, name = line:find("^<%-*(%w+)%-*>", i) + f.size = 1 + newi - i + f.value = name + i = newi + else + error("bad field char '"..c.."' in '"..line.."'") + end + if f.value:find("[0-9]+") then + f.literal = true + f.variable = false + else + f.literal = false + f.variable = true + end + -- Convert from PowerPC numbering to sane numbering + f.pos = 33-(f.pos + f.size) + fields[#fields+1] = f + if f.value then + fields[f.value] = f + end + end + i = i + 1 + end + + local value = 0 + for _, f in ipairs(fields) do + if f.literal then + local s = math.pow(2, f.pos) + value = value + f.value*s + end + end + fields.value = value + + return fields +end + + +local function emit(fields, code) + local mask = 0 + local value = 0 + for _, f in ipairs(fields) do + if f.literal then + local s = math.pow(2, f.pos) + local m = math.pow(2, f.size) - 1 + mask = mask + m*s + value = value + f.value*s + end + end + + print(string.format("if ((value & 0x%x) == 0x%x) {", mask, value)) + for _, f in ipairs(fields) do + if f.variable then + local m = math.pow(2, f.size) - 1 + print(string.format("uint32_t %s = (value >> %d) & 0x%x;", f.value, f.pos, m)) + end + end + + print(code) + print("return;") + print("}") +end + +while true do + local line = io.stdin:read("*l") + if not line then + break + end + line = line:gsub("#.*$", "") + line = line:gsub(" *$", "") + if line ~= "" then + local fields = parsefields(line) + local syntax = parsesyntax(line:sub(34, #line)) + insns[#insns+1] = { + fields=parsefields(line), + syntax=parsesyntax(line:sub(34, #line)) + } + end +end + +local definitionsfp = io.open(args[1], "w") +for word, value in pairs(words) do + definitionsfp:write("%token OP_", tostring(value), " /* ", word, " */\n") +end +definitionsfp:close() + +local tokensfp = io.open(args[2], "w") +for word, value in pairs(words) do + tokensfp:write("0, OP_", tostring(value), ", 0, \"", word, "\",\n") +end +tokensfp:close() + +local rulesfp = io.open(args[3], "w") +rulesfp:write("operation\n") +for index, insn in ipairs(insns) do + if index == 1 then + rulesfp:write("\t:") + else + rulesfp:write("\t|") + end + for _, word in ipairs(insn.syntax) do + if word.word then + rulesfp:write(" OP_", tostring(word.word)) + end + if word.punct then + rulesfp:write(" ", word.punct) + end + if word.token then + rulesfp:write(" ", word.token) + end + end + rulesfp:write("\n") + + rulesfp:write("\t{ emit4(", string.format("0x%08x", insn.fields.value)) + for wordindex, word in ipairs(insn.syntax) do + if word.token then + for _, alias in ipairs(word) do + local f = insn.fields[alias] + if not f then + error("reference to field "..alias.." which doesn't exist") + end + local mask = math.pow(2, f.size) - 1 + rulesfp:write(" | (($", wordindex, + " & ", string.format("0x%x", mask), ") << ", f.pos, ")") + end + end + end + rulesfp:write("); }\n") +end +rulesfp:close() + diff --git a/mach/proto/as/build.lua b/mach/proto/as/build.lua index 9782b4b4b..52536cbbf 100644 --- a/mach/proto/as/build.lua +++ b/mach/proto/as/build.lua @@ -2,7 +2,8 @@ include("first/yacc.lua") definerule("build_as", { - arch = { type="string" } + arch = { type="string" }, + deps = { type="targets", default={} }, }, function(e) -- Remember this is executed from the caller's directory; local @@ -25,6 +26,7 @@ definerule("build_as", "mach/proto/as/comm1.h", "h+emheaders", archlib, + e.deps, }, } @@ -43,7 +45,8 @@ definerule("build_as", "h+emheaders", "modules/src/object+lib", archlib, - yaccfiles + yaccfiles, + e.deps } } end diff --git a/mach/proto/as/comm0.h b/mach/proto/as/comm0.h index 60fb172b4..03b48f75e 100644 --- a/mach/proto/as/comm0.h +++ b/mach/proto/as/comm0.h @@ -22,6 +22,7 @@ _include #include #include #include +#include #endif /* ========== ON/OFF options (use #define in mach0.c) ========== */ diff --git a/plat/linuxmips/build-pkg.lua b/plat/linuxmips/build-pkg.lua new file mode 100644 index 000000000..6aec05157 --- /dev/null +++ b/plat/linuxmips/build-pkg.lua @@ -0,0 +1,25 @@ +include("plat/build.lua") + +--ackfile { +-- name = "boot", +-- srcs = { "./boot.s" }, +-- vars = { plat = "linuxppc" } +--} +-- +--build_plat_libs { +-- name = "libs", +-- arch = "powerpc", +-- plat = "linuxppc", +--} + +installable { + name = "pkg", + map = { + "+tools", +-- "+libs", + "./include+pkg", +-- ["$(PLATIND)/linuxppc/boot.o"] = "+boot", +-- ["$(PLATIND)/linuxppc/libsys.a"] = "./libsys+lib", + } +} + diff --git a/plat/linuxmips/build-tools.lua b/plat/linuxmips/build-tools.lua new file mode 100644 index 000000000..04a385d47 --- /dev/null +++ b/plat/linuxmips/build-tools.lua @@ -0,0 +1,30 @@ +include("plat/build.lua") + +build_as { + name = "as", + arch = "mips", + deps = { "mach/mips/as+astables" } +} + +--build_mcg { +-- name = "mcg", +-- arch = "powerpc", +--} +-- +--build_top { +-- name = "top", +-- arch = "powerpc", +--} + +return installable { + name = "tools", + map = { + ["$(PLATDEP)/linuxmips/as"] = "+as", + --["$(PLATDEP)/linuxppc/ncg"] = "+ncg", + --["$(PLATDEP)/linuxppc/mcg"] = "+mcg", + --["$(PLATDEP)/linuxppc/top"] = "+top", + ["$(PLATIND)/descr/linuxmips"] = "./descr", + "util/amisc+aelflod-pkg", + "util/opt+pkg", + } +} diff --git a/plat/linuxmips/descr b/plat/linuxmips/descr new file mode 100644 index 000000000..7ddaf941b --- /dev/null +++ b/plat/linuxmips/descr @@ -0,0 +1,87 @@ +# plat/linuxppc/descr + +var w=4 +var wa=4 +var p={w} +var pa={w} +var s=2 +var sa={s} +var l={w} +var la={w} +var f={w} +var fa={w} +var d=8 +var da={d} +var x=8 +var xa={x} +var ARCH=mips +var PLATFORM=linuxmips +var PLATFORMDIR={EM}/share/ack/{PLATFORM} +var CPP_F=-D__unix +var ALIGN=-a0:4 -a1:4 -a2:4 -a3:4 -b0:0x00400054 +var MACHOPT_F=-m2 +var EGO_PLAT_FLAGS=-M{EM}/share/ack/ego/{ARCH}.descr + +# Override the setting in fe so that files compiled for linuxppc can see +# the platform-specific headers. + +var C_INCLUDES=-I{EM}/share/ack/linux/include -I{EM}/share/ack/include/ansi + +name be + from .m.g + to .s + program {EM}/lib/ack/{PLATFORM}/ncg + mapflag -gdb GF=-gdb + args {GF?} < + stdout + need .e +end +name asopt + from .s + to .so + program {EM}/lib/ack/{PLATFORM}/top + args + optimizer + stdin + stdout +end +name as + from .s.so + to .o + program {EM}/lib/ack/{PLATFORM}/as + args - -o > < + prep cond +end +name led + from .o.a + to .out + program {EM}/lib/ack/em_led + mapflag -l* LNAME={PLATFORMDIR}/lib* + mapflag -fp FLOATS={EM}/{LIB}fp + args {ALIGN} {SEPID?} \ + ({RTS}:.b=-u _i_main) \ + (.e:{HEAD}={PLATFORMDIR}/boot.o) \ + ({RTS}:.ocm.bas.b={PLATFORMDIR}/c-ansi.o) \ + ({RTS}:.c={PLATFORMDIR}/c-ansi.o) \ + ({RTS}:.mod={PLATFORMDIR}/modula2.o) \ + ({RTS}:.p={PLATFORMDIR}/pascal.o) \ + -o > < \ + (.p:{TAIL}={PLATFORMDIR}/libpascal.a) \ + (.b:{TAIL}={PLATFORMDIR}/libb.a) \ + (.bas:{TAIL}={PLATFORMDIR}/libbasic.a) \ + (.mod:{TAIL}={PLATFORMDIR}/libmodula2.a) \ + (.ocm:{TAIL}={PLATFORMDIR}/liboccam.a) \ + (.ocm.bas.mod.b.c.p:{TAIL}={PLATFORMDIR}/libc.a) \ + {FLOATS?} \ + (.e:{TAIL}={PLATFORMDIR}/libem.a \ + {PLATFORMDIR}/libsys.a \ + {PLATFORMDIR}/libend.a) + linker +end +name cv + from .out + to .exe + program {EM}/bin/aelflod + args -m20 -b < > + outfile linuxppc.exe +end diff --git a/plat/linuxmips/include/build.lua b/plat/linuxmips/include/build.lua new file mode 100644 index 000000000..747e52089 --- /dev/null +++ b/plat/linuxmips/include/build.lua @@ -0,0 +1,4 @@ +installable { + name = "pkg", + map = { "plat/linux/include+pkg" } +} -- 2.34.1