// BNCG6.bcpl - BCPL Compiler // Nova Code Generator, Instruction generation routines // Copyright Xerox Corporation 1980 ///*DCS* Last modified on Sat 02 Nov 74 by DCS. // Paxton, 9-14-78: unsigned compares get "bncgx" static [ opcode = nil defer = nil addrsign = nil addrval = nil star = nil indx = nil cary = nil shft = nil noload = nil reg1 = nil reg2 = nil skip = nil ] let CG(op) be [ test PassTwo then op = Code!PC or Code!PC = op if SWCode do [ WW($*n) WriteO(op); WW($*t) test LabelDef then WriteS("LAB") or WriteS(" "); LabelDef = false WriteO(PC) WW($*t) WriteInstr(op) WW($*t) ] PC = PC + 1 if PC ge PCmax do CGreport(0) ] and CGn(n) be [ test PassTwo then n = Code!PC or Code!PC = n if SWCode do [ WW($*n) WriteO(n); WW($*t) test LabelDef then WriteS("LAB") or WriteS(" "); LabelDef = false WriteO(PC) WW($*t) WriteS(" ") WriteO(n) WW($*t) ] PC = PC + 1 if PC ge PCmax do CGreport(0) ] and WriteInstr(op) be [winst test (op & #100000) eq 0 then [mref opcode = selecton (op & #074000) rshift 11 into [ case #00: "jmp " case #01: "jsr " case #02: "isz " case #03: "dsz " case #04: "lda 0 " case #05: "lda 1 " case #06: "lda P " case #07: "lda X " case #10: "sta 0 " case #11: "sta 1 " case #12: "sta P " case #13: "sta X " case #14: SWAlto?"ALTO ","IO 0 " case #15: SWAlto?"JSRII","IO 1 " case #16: SWAlto?"ALTO ","IO P " case #17: SWAlto?"ALTO ","IO X " ] defer = ((op & #002000) eq 0 ? " ", " @") let paddr = op & #377; let maddr = Wval(paddr) addrsign = (paddr eq maddr ? 0, $-) maddr = (maddr gr 0 ? maddr, maddr eq 0 ? 0, -maddr) star = 0 switchon (op & #001400) rshift 8 into [ case 0: indx = ",Z"; addrval = paddr; addrsign = 0; endcase case 1: indx = " "; star = $.; addrval = maddr if addrsign eq 0 do addrsign = $+; endcase case 2: indx = ",P"; addrval = maddr; endcase case 3: indx = ",X"; addrval = maddr; endcase ] WriteS(opcode) WriteS(defer) if star ne 0 do WW(star) if addrsign ne 0 do WW(addrsign) WriteOct(addrval) WriteS(indx) return ]mref or [regop opcode = selecton (op & #003400) rshift 8 into [ case 0: "com" case 1: "neg" case 2: "mov" case 3: "inc" case 4: "adc" case 5: "sub" case 6: "add" case 7: "and" ] cary = selecton (op & #000060) rshift 4 into [ case 0: 0 case 1: $z case 2: $o case 3: $c ] shft = selecton (op & #000300) rshift 6 into [ case 0: 0 case 1: $l case 2: $r case 3: $s ] noload = ((op & #000010) eq 0 ? 0, $#) reg1 = selecton (op & #060000) rshift 13 into [ case 0: $0 case 1: $1 case 2: $P case 3: $X ] reg2 = selecton (op & #014000) rshift 11 into [ case 0: $0 case 1: $1 case 2: $P case 3: $X ] skip = selecton (op & #000007) into [ case 0: " " case 1: "skp" case 2: "szc" case 3: "snc" case 4: "szr" case 5: "snr" case 6: "sez" case 7: "sbn" ] WriteS(opcode) if cary ne 0 do WW(cary) if shft ne 0 do WW(shft) if noload ne 0 do WW(noload) WW($*s) WW(reg1) WW($*s) WW(reg2) WW($*s) WriteS(skip) return ]regop ]winst and WriteLabel(l) be [ WriteS(" (LAB") WriteOct(plabdefvec!l) WW($)) ] and WriteName(n) be [ if n eq 0 do [ WriteS("??"); return ] ///*DCS* Better Symbol Table WriteS(LookForSym(n)) ] and WriteSkip(op) be [ let ac1 = (op rshift 13) & #3 let ac2 = (op rshift 11) & #3 op = op & #103777 let skip = selecton op into [ case Isne0: "ne 0" case Iseq0: "eq 0" case Isge0: "ge 0" case Isgr0: "gr 0" case Isle0: "le 0" case Isls0: "ls 0" case Isne: "ne" case Iseq: "eq" case Isge: "ge" case Isgr: "gr" case Isle: "le" case Isls: "ls" case Isuge: "uge" case Isugr: "ugr" case Isule: "ule" case Isuls: "uls" case Isne1: "ne -1" case Iseq1: "eq -1" default: "??" ] WriteS("// skip if ") test ac2 eq X then WriteS("X ") or [ WriteS("AC"); WriteOct(ac2); WW($*s) ] WriteS(skip) unless ac1 eq ac2 do test ac1 eq X then WriteS(" X") or [ WriteS(" AC"); WriteOct(ac1); WW($*s) ] ]