diff options
Diffstat (limited to 'src/cmd/5a/lex.go')
-rw-r--r-- | src/cmd/5a/lex.go | 371 |
1 files changed, 371 insertions, 0 deletions
diff --git a/src/cmd/5a/lex.go b/src/cmd/5a/lex.go new file mode 100644 index 0000000000..1afd827793 --- /dev/null +++ b/src/cmd/5a/lex.go @@ -0,0 +1,371 @@ +// Inferno utils/5a/lex.c +// http://code.google.com/p/inferno-os/source/browse/utils/5a/lex.c +// +// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. +// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) +// Portions Copyright © 1997-1999 Vita Nuova Limited +// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) +// Portions Copyright © 2004,2006 Bruce Ellis +// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) +// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others +// Portions Copyright © 2009 The Go Authors. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +//go:generate go tool yacc a.y + +package main + +import ( + "cmd/internal/asm" + "cmd/internal/obj" + "cmd/internal/obj/arm" +) + +var ( + yyerror = asm.Yyerror + nullgen obj.Addr + stmtline int32 +) + +const Always = arm.C_SCOND_NONE + +func main() { + cinit() + + asm.LSCONST = LSCONST + asm.LCONST = LCONST + asm.LFCONST = LFCONST + asm.LNAME = LNAME + asm.LVAR = LVAR + asm.LLAB = LLAB + + asm.Lexinit = lexinit + asm.Cclean = cclean + asm.Yyparse = yyparse + + asm.Thechar = '5' + asm.Thestring = "arm" + asm.Thelinkarch = &arm.Linkarm + + asm.Main() +} + +type yy struct{} + +func (yy) Lex(v *yySymType) int { + var av asm.Yylval + tok := asm.Yylex(&av) + v.sym = av.Sym + v.lval = int32(av.Lval) + v.sval = av.Sval + v.dval = av.Dval + return tok +} + +func (yy) Error(msg string) { + asm.Yyerror("%s", msg) +} + +func yyparse() { + yyParse(yy{}) +} + +var lexinit = []asm.Lextab{ + {"SP", LSP, obj.NAME_AUTO}, + {"SB", LSB, obj.NAME_EXTERN}, + {"FP", LFP, obj.NAME_PARAM}, + {"PC", LPC, obj.TYPE_BRANCH}, + + {"R", LR, 0}, + + {"R0", LREG, arm.REG_R0}, + {"R1", LREG, arm.REG_R1}, + {"R2", LREG, arm.REG_R2}, + {"R3", LREG, arm.REG_R3}, + {"R4", LREG, arm.REG_R4}, + {"R5", LREG, arm.REG_R5}, + {"R6", LREG, arm.REG_R6}, + {"R7", LREG, arm.REG_R7}, + {"R8", LREG, arm.REG_R8}, + {"R9", LREG, arm.REG_R9}, + {"g", LREG, arm.REG_R10}, // avoid unintentionally clobber g using R10 + {"R11", LREG, arm.REG_R11}, + {"R12", LREG, arm.REG_R12}, + {"R13", LREG, arm.REG_R13}, + {"R14", LREG, arm.REG_R14}, + {"R15", LREG, arm.REG_R15}, + {"F", LF, 0}, + {"F0", LFREG, arm.REG_F0}, + {"F1", LFREG, arm.REG_F1}, + {"F2", LFREG, arm.REG_F2}, + {"F3", LFREG, arm.REG_F3}, + {"F4", LFREG, arm.REG_F4}, + {"F5", LFREG, arm.REG_F5}, + {"F6", LFREG, arm.REG_F6}, + {"F7", LFREG, arm.REG_F7}, + {"F8", LFREG, arm.REG_F8}, + {"F9", LFREG, arm.REG_F9}, + {"F10", LFREG, arm.REG_F10}, + {"F11", LFREG, arm.REG_F11}, + {"F12", LFREG, arm.REG_F12}, + {"F13", LFREG, arm.REG_F13}, + {"F14", LFREG, arm.REG_F14}, + {"F15", LFREG, arm.REG_F15}, + {"C", LC, 0}, + {"C0", LCREG, 0}, + {"C1", LCREG, 1}, + {"C2", LCREG, 2}, + {"C3", LCREG, 3}, + {"C4", LCREG, 4}, + {"C5", LCREG, 5}, + {"C6", LCREG, 6}, + {"C7", LCREG, 7}, + {"C8", LCREG, 8}, + {"C9", LCREG, 9}, + {"C10", LCREG, 10}, + {"C11", LCREG, 11}, + {"C12", LCREG, 12}, + {"C13", LCREG, 13}, + {"C14", LCREG, 14}, + {"C15", LCREG, 15}, + {"CPSR", LPSR, arm.REG_CPSR}, + {"SPSR", LPSR, arm.REG_SPSR}, + {"FPSR", LFCR, arm.REG_FPSR}, + {"FPCR", LFCR, arm.REG_FPCR}, + {".EQ", LCOND, arm.C_SCOND_EQ}, + {".NE", LCOND, arm.C_SCOND_NE}, + {".CS", LCOND, arm.C_SCOND_HS}, + {".HS", LCOND, arm.C_SCOND_HS}, + {".CC", LCOND, arm.C_SCOND_LO}, + {".LO", LCOND, arm.C_SCOND_LO}, + {".MI", LCOND, arm.C_SCOND_MI}, + {".PL", LCOND, arm.C_SCOND_PL}, + {".VS", LCOND, arm.C_SCOND_VS}, + {".VC", LCOND, arm.C_SCOND_VC}, + {".HI", LCOND, arm.C_SCOND_HI}, + {".LS", LCOND, arm.C_SCOND_LS}, + {".GE", LCOND, arm.C_SCOND_GE}, + {".LT", LCOND, arm.C_SCOND_LT}, + {".GT", LCOND, arm.C_SCOND_GT}, + {".LE", LCOND, arm.C_SCOND_LE}, + {".AL", LCOND, arm.C_SCOND_NONE}, + {".U", LS, arm.C_UBIT}, + {".S", LS, arm.C_SBIT}, + {".W", LS, arm.C_WBIT}, + {".P", LS, arm.C_PBIT}, + {".PW", LS, arm.C_WBIT | arm.C_PBIT}, + {".WP", LS, arm.C_WBIT | arm.C_PBIT}, + {".F", LS, arm.C_FBIT}, + {".IBW", LS, arm.C_WBIT | arm.C_PBIT | arm.C_UBIT}, + {".IAW", LS, arm.C_WBIT | arm.C_UBIT}, + {".DBW", LS, arm.C_WBIT | arm.C_PBIT}, + {".DAW", LS, arm.C_WBIT}, + {".IB", LS, arm.C_PBIT | arm.C_UBIT}, + {".IA", LS, arm.C_UBIT}, + {".DB", LS, arm.C_PBIT}, + {".DA", LS, 0}, + {"@", LAT, 0}, + {"AND", LTYPE1, arm.AAND}, + {"EOR", LTYPE1, arm.AEOR}, + {"SUB", LTYPE1, arm.ASUB}, + {"RSB", LTYPE1, arm.ARSB}, + {"ADD", LTYPE1, arm.AADD}, + {"ADC", LTYPE1, arm.AADC}, + {"SBC", LTYPE1, arm.ASBC}, + {"RSC", LTYPE1, arm.ARSC}, + {"ORR", LTYPE1, arm.AORR}, + {"BIC", LTYPE1, arm.ABIC}, + {"SLL", LTYPE1, arm.ASLL}, + {"SRL", LTYPE1, arm.ASRL}, + {"SRA", LTYPE1, arm.ASRA}, + {"MUL", LTYPE1, arm.AMUL}, + {"MULA", LTYPEN, arm.AMULA}, + {"DIV", LTYPE1, arm.ADIV}, + {"MOD", LTYPE1, arm.AMOD}, + {"MULL", LTYPEM, arm.AMULL}, + {"MULAL", LTYPEM, arm.AMULAL}, + {"MULLU", LTYPEM, arm.AMULLU}, + {"MULALU", LTYPEM, arm.AMULALU}, + {"MVN", LTYPE2, arm.AMVN}, /* op2 ignored */ + {"MOVB", LTYPE3, arm.AMOVB}, + {"MOVBU", LTYPE3, arm.AMOVBU}, + {"MOVH", LTYPE3, arm.AMOVH}, + {"MOVHU", LTYPE3, arm.AMOVHU}, + {"MOVW", LTYPE3, arm.AMOVW}, + {"MOVD", LTYPE3, arm.AMOVD}, + {"MOVDF", LTYPE3, arm.AMOVDF}, + {"MOVDW", LTYPE3, arm.AMOVDW}, + {"MOVF", LTYPE3, arm.AMOVF}, + {"MOVFD", LTYPE3, arm.AMOVFD}, + {"MOVFW", LTYPE3, arm.AMOVFW}, + {"MOVWD", LTYPE3, arm.AMOVWD}, + {"MOVWF", LTYPE3, arm.AMOVWF}, + {"LDREX", LTYPE3, arm.ALDREX}, + {"LDREXD", LTYPE3, arm.ALDREXD}, + {"STREX", LTYPE9, arm.ASTREX}, + {"STREXD", LTYPE9, arm.ASTREXD}, + + /* + {"NEGF", LTYPEI, ANEGF}, + {"NEGD", LTYPEI, ANEGD}, + {"SQTF", LTYPEI, ASQTF}, + {"SQTD", LTYPEI, ASQTD}, + {"RNDF", LTYPEI, ARNDF}, + {"RNDD", LTYPEI, ARNDD}, + {"URDF", LTYPEI, AURDF}, + {"URDD", LTYPEI, AURDD}, + {"NRMF", LTYPEI, ANRMF}, + {"NRMD", LTYPEI, ANRMD}, + */ + {"ABSF", LTYPEI, arm.AABSF}, + {"ABSD", LTYPEI, arm.AABSD}, + {"SQRTF", LTYPEI, arm.ASQRTF}, + {"SQRTD", LTYPEI, arm.ASQRTD}, + {"CMPF", LTYPEL, arm.ACMPF}, + {"CMPD", LTYPEL, arm.ACMPD}, + {"ADDF", LTYPEK, arm.AADDF}, + {"ADDD", LTYPEK, arm.AADDD}, + {"SUBF", LTYPEK, arm.ASUBF}, + {"SUBD", LTYPEK, arm.ASUBD}, + {"MULF", LTYPEK, arm.AMULF}, + {"MULD", LTYPEK, arm.AMULD}, + {"DIVF", LTYPEK, arm.ADIVF}, + {"DIVD", LTYPEK, arm.ADIVD}, + {"B", LTYPE4, arm.AB}, + {"BL", LTYPE4, arm.ABL}, + {"BX", LTYPEBX, arm.ABX}, + {"BEQ", LTYPE5, arm.ABEQ}, + {"BNE", LTYPE5, arm.ABNE}, + {"BCS", LTYPE5, arm.ABCS}, + {"BHS", LTYPE5, arm.ABHS}, + {"BCC", LTYPE5, arm.ABCC}, + {"BLO", LTYPE5, arm.ABLO}, + {"BMI", LTYPE5, arm.ABMI}, + {"BPL", LTYPE5, arm.ABPL}, + {"BVS", LTYPE5, arm.ABVS}, + {"BVC", LTYPE5, arm.ABVC}, + {"BHI", LTYPE5, arm.ABHI}, + {"BLS", LTYPE5, arm.ABLS}, + {"BGE", LTYPE5, arm.ABGE}, + {"BLT", LTYPE5, arm.ABLT}, + {"BGT", LTYPE5, arm.ABGT}, + {"BLE", LTYPE5, arm.ABLE}, + {"BCASE", LTYPE5, arm.ABCASE}, + {"SWI", LTYPE6, arm.ASWI}, + {"CMP", LTYPE7, arm.ACMP}, + {"TST", LTYPE7, arm.ATST}, + {"TEQ", LTYPE7, arm.ATEQ}, + {"CMN", LTYPE7, arm.ACMN}, + {"MOVM", LTYPE8, arm.AMOVM}, + {"SWPBU", LTYPE9, arm.ASWPBU}, + {"SWPW", LTYPE9, arm.ASWPW}, + {"RET", LTYPEA, obj.ARET}, + {"RFE", LTYPEA, arm.ARFE}, + {"TEXT", LTYPEB, obj.ATEXT}, + {"GLOBL", LGLOBL, obj.AGLOBL}, + {"DATA", LTYPEC, obj.ADATA}, + {"CASE", LTYPED, arm.ACASE}, + {"END", LTYPEE, obj.AEND}, + {"WORD", LTYPEH, arm.AWORD}, + {"NOP", LTYPEI, obj.ANOP}, + {"MCR", LTYPEJ, 0}, + {"MRC", LTYPEJ, 1}, + {"PLD", LTYPEPLD, arm.APLD}, + {"UNDEF", LTYPEE, obj.AUNDEF}, + {"CLZ", LTYPE2, arm.ACLZ}, + {"MULWT", LTYPE1, arm.AMULWT}, + {"MULWB", LTYPE1, arm.AMULWB}, + {"MULAWT", LTYPEN, arm.AMULAWT}, + {"MULAWB", LTYPEN, arm.AMULAWB}, + {"USEFIELD", LTYPEN, obj.AUSEFIELD}, + {"PCDATA", LTYPEPC, obj.APCDATA}, + {"FUNCDATA", LTYPEF, obj.AFUNCDATA}, +} + +func cinit() { +} + +func isreg(g *obj.Addr) bool { + return true +} + +func cclean() { + outcode(obj.AEND, Always, &nullgen, 0, &nullgen) +} + +var bcode = []int{ + arm.ABEQ, + arm.ABNE, + arm.ABCS, + arm.ABCC, + arm.ABMI, + arm.ABPL, + arm.ABVS, + arm.ABVC, + arm.ABHI, + arm.ABLS, + arm.ABGE, + arm.ABLT, + arm.ABGT, + arm.ABLE, + arm.AB, + obj.ANOP, +} + +var lastpc *obj.Prog + +func outcode(a, scond int32, g1 *obj.Addr, reg int32, g2 *obj.Addr) { + var p *obj.Prog + var pl *obj.Plist + + /* hack to make B.NE etc. work: turn it into the corresponding conditional */ + if a == arm.AB { + a = int32(bcode[(scond^arm.C_SCOND_XOR)&0xf]) + scond = (scond &^ 0xf) | Always + } + + if asm.Pass == 1 { + goto out + } + + p = new(obj.Prog) + *p = obj.Prog{} + p.Ctxt = asm.Ctxt + p.As = int16(a) + p.Lineno = stmtline + p.Scond = uint8(scond) + p.From = *g1 + p.Reg = int16(reg) + p.To = *g2 + p.Pc = int64(asm.PC) + + if lastpc == nil { + pl = obj.Linknewplist(asm.Ctxt) + pl.Firstpc = p + } else { + lastpc.Link = p + } + lastpc = p + +out: + if a != obj.AGLOBL && a != obj.ADATA { + asm.PC++ + } +} |