⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 codesubs.p

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 P
字号:
(*#@(#)codesubs.p	4.1	Ultrix	7/17/90 *)(**************************************************************************** *									    * *  Copyright (c) 1984 by						    * *  DIGITAL EQUIPMENT CORPORATION, Maynard, Massachusetts.		    * *  All rights reserved.						    * * 									    * *  This software is furnished under a license and may be used and copied   * *  only in  accordance with  the  terms  of  such  license  and with the   * *  inclusion of the above copyright notice. This software or  any  other   * *  copies thereof may not be provided or otherwise made available to any   * *  other person.  No title to and ownership of  the  software is  hereby   * *  transferred.							    * * 									    * *  The information in this software is  subject to change without notice   * *  and  should  not  be  construed as  a commitment by DIGITAL EQUIPMENT   * *  CORPORATION.							    * * 									    * *  DIGITAL assumes no responsibility for the use  or  reliability of its   * *  software on equipment which is not supplied by DIGITAL.		    * * 									    * *									    * ****************************************************************************)#include "globals.h"#include "util.h"#include "codesubs.h"#include "input.h"function DoJumps{:boolean};var lab1, lab2 : LabelNumber; didit : boolean;	{ if tjp, generate jump for nextjump condition }	{ if fjp, generate jump for not nextjump condition }	{ otherwise, generate code to set a boolean and push it on top }	{ when done, indicate whether instruction was done }begin    if opcode = opnot then begin	didit := TRUE;	nextjump := jumpopposite[nextjump];    end else if opcode = optjp then begin	Op(jumpnames[nextjump]); writelabel(1); L;	didit := TRUE;	nextjump := jcnone;     { jump was handled }    end else if opcode = opfjp then begin	Op(jumpnames[jumpopposite[nextjump]]); writelabel(1); L;	didit := TRUE;	nextjump := jcnone;     { jump was handled }    end else begin	PushReg(tboolean,BOOLSIZE,AllocReg(REGEES,top+1,tboolean));	lab1 := NewLabel;	lab2 := NewLabel;	Op(jumpnames[nextjump]); Lab(lab1); L;	Op('clrl'); Opnd(top); L;	Op('jbr'); Lab(lab2); L;	Lab(lab1); C(':'); L;	Op('movl'); S('$1'); X; Opnd(top); L;	Lab(lab2); C(':'); L;	didit := FALSE;	nextjump := jcnone;     { jump was handled }    end;    DoJumps := didit;end;{ MultiWordBinOp:  top=count }procedure MultiWordBinOp{(op : ShortString; left, right : EESElement)};var    lab : LabelNumber;begin    if ees[top].kind <> EESDATA then begin	Error('MultiWordBinOp: expected data for count');    end;    ees[top].constInt := ees[top].constInt - 1;    Eval(top);    Point(left);    Point(right);    lab := NewLabel;    Lab(lab); C(':'); Op(op); Opnd(left); C('['); Opnd(top); C(']'); X;	    Opnd(right); C('['); Opnd(top); C(']'); L;    Op('sobgeq'); Opnd(top); X; Lab(lab); L;    Pop(1);end;{ MultiWordUnOp:  top=count }procedure MultiWordUnOp{(op : ShortString; opnd : EESElement)};var    lab : LabelNumber;begin    if ees[top].kind <> EESDATA then begin	Error('MultiWordUnOp: expected data for count');    end;    ees[top].constInt := ees[top].constInt - 1;    Eval(top);    Point(opnd);    lab := NewLabel;    Lab(lab); C(':'); Op(op); Opnd(opnd); C('['); Opnd(top); C(']'); L;    Op('sobgeq'); Opnd(top); X; Lab(lab); L;    Pop(1);end;procedure Compare{(ptype : pcodetype; size : sizerange)};var    loop, exit : LabelNumber;begin    if ptype = tlongreal then begin	Check(top,2*WORDSIZE);	Check(top-1,2*WORDSIZE);	Op('cmpd'); Opnd(top-1); X; Opnd(top); L;	Pop(2);    end else if size > WORDSIZE then begin	PushConst(tinteger,WORDSIZE,size div WORDSIZE);	Eval(top);	Point(top-1);	Point(top-2);	loop := NewLabel;	exit := NewLabel;	Lab(loop); C(':'); 	Op('cmpl'); Opnd(top-2); C('+'); X; Opnd(top-1); C('+'); L;	Op('jneq'); Lab(exit); L;	Op('sobgtr'); Opnd(top); X; Lab(loop); L;	Pop(1);	{ tricky: if size not a multiple, we are now pointing at remainder. }	{ make pointer into variables and fix sizes, then recurse for compare }	size := size - (size div WORDSIZE * WORDSIZE);	if size > 0 then begin	    ees[top].kind := EESVAR;	    ees[top].size := size;	    ees[top-1].kind := EESVAR;	    ees[top-1].size := size;	    Compare(ptype,size);	end else begin	    Pop(2);	end;	Lab(exit); C(':'); L;    end else if size = BYTESIZE then begin	Check(top,BYTESIZE);	Check(top-1,BYTESIZE);	Op('cmpb'); Opnd(top-1); X; Opnd(top); L;	Pop(2);    end else begin	Check(top,WORDSIZE);	Check(top-1,WORDSIZE);	if ptype = treal then begin	    Op('cmpf'); Opnd(top-1); X; Opnd(top); L;	end else if (ees[top].kind = EESDATA) and (ees[top].dreg = NULLREG) and	    (ees[top].constInt = 0)	then begin	    Op('tstl'); Opnd(top-1); L;	end else begin	    Op('cmpl'); Opnd(top-1); X; Opnd(top); L;	end;	Pop(2);    end;end;procedure CallProcOp{(op : opcodes)};var    size : sizerange;    numParams : integer;begin    size := Int(opd^[2]);    numParams := Int(opd^[3]);    if op = opcip then begin	CallProc(op,opd11,size,numParams,{dummy parameter}opd^[1]);    end else begin	CallProc(op,opd11,size,numParams,opd^[4]);    end;end;procedure CallProc{(op : opcodes; ctype : char; size : sizerange; numParams : integer; var procName : operandstring)};var    numParamWords : integer;    i : integer;    ptype : pcodetype;    cipflag : integer;begin    if op = opcip then begin	cipflag := 1;    end else begin	cipflag := 0;    end;    ptype := associatedType[ctype];    SaveRegs(top-numParams-cipflag);    numParamWords := 0;    { push params on stack (backwards!) }    for i := 1 to numParams do begin	if ees[top].kind = EESADDR then begin	    if (ees[top].sreg <> NULLREG) and		    ((ees[top].sunits mod WORDSIZE) = 0)	    then begin		CheckRegs(top,WORDSIZE);		Op('pushal'); Opnd(top); L;	    end else begin		CheckRegs(top,BYTESIZE);		Op('pushab'); Opnd(top); L;	    end;	    numParamWords := numParamWords + 1;	end else if ees[top].ptype = tlongreal then begin	    { two-word real }	    Check(top,2*WORDSIZE);	    Op('movq'); Opnd(top); X; S('-(sp)'); L;	    numParamWords := numParamWords + 2;	end else if (ees[top].kind = EESDATA) or (ees[top].size <= WORDSIZE)	then begin	    { one word }	    Check(top,WORDSIZE);	    Op('pushl'); Opnd(top); L;	    numParamWords := numParamWords + 1;	end else begin	    { must be a multi-word quantity.  Push address }	    if ees[top].indirect then begin		{ indirect, make it a variable address }		ees[top].kind := EESVAR;		ees[top].ptype := taddress;		ees[top].size := ADDRSIZE;		ees[top].indirect := false;	    end;	    { push parameter on stack }	    Point(top);	    Op('pushl'); R(ees[top].breg); L;	    numParamWords := numParamWords + 1;	end;	Pop(1);    end;    if op = opcip then begin	Point(top);	Op('calls'); C('$'); I(numParamWords); X; Opnd(top); L;	Pop(1);    end else if op = opcup then begin	Op('jsb'); C('_'); SO(procName); L;	if numParamWords <> 0 then begin	    Op('addl2'); C('$'); I(numParamWords*4); X; R(sp); L;	end;    end else begin	Op('calls'); C('$'); I(numParamWords); X; C('_'); SO(procName); L;    end;    ClearDisp;    if ptype <> tproc then begin	PushReg(ptype,size,AllocReg(REGRETURN,top+1,ptype));	if (size > WORDSIZE) and (ptype <> tlongreal) then begin	    { reg is address of return value, make it base address }	    ees[top].kind := EESVAR;	    ees[top].breg := ees[top].dreg;	    ees[top].dreg := NULLREG;	    MakeMultiWordTemp(top);	end;    end;    RestoreRegs(top);end;procedure MakeBaseAddress{(e:EESElement)};var    saveoffset : integer;begin    case ees[e].kind of	EESVAR, EESDATA : begin	    saveoffset := ees[e].constInt * BYTESIZE;   	    ees[e].constInt := 0;	    if ees[e].kind = EESVAR then begin		if not ees[e].indirect and AddrIsTReg(e) then begin		    { make it dreg: will become breg below }		    ees[e].dreg := MemTReg(ees[e].addrOffset);		    ClearAddress(e);		end else begin		    Eval(e);		end;	    end;	    ees[e].breg := ees[e].dreg;	    ees[e].dreg := NULLREG;	    ees[e].kind := EESADDR;	    ees[e].addrOffset := saveoffset;	end;	EESADDR : begin	end;    end;end;procedure MakeVariable{(e:EESElement)};var    constOffset : integer;begin    case ees[e].kind of	EESADDR : begin	    { make address into variable }	    ees[e].kind := EESVAR;	end;	EESVAR : begin	    if (ees[e].sreg <> NULLREG) or (ees[e].constInt <> 0) or		    ees[e].indirect	    then begin		{ get value, make base address of variable }		constOffset := ees[e].constInt * BYTESIZE;		ees[e].constInt := 0;		if not ees[e].indirect and AddrIsTReg(e) then begin		    { make it dreg: will become breg below }		    ees[e].dreg := MemTReg(ees[e].addrOffset);		    ClearAddress(e);		end else begin		    Eval(e);		end;		ees[e].breg := ees[e].dreg;		ees[e].dreg := NULLREG;		ClearAddress(e);		ees[e].addrOffset := constOffset;		ees[e].kind := EESVAR;	    end else begin		{ use indirect addressing (no subscripting allowed) }		ees[e].indirect := true;	    end;	end;	EESDATA : begin	    { get value, make base address of variable }	    ees[e].breg := ees[e].dreg;	    ees[e].dreg := NULLREG;	    ClearAddress(e);	    ees[e].addrOffset := ees[e].constInt * BYTESIZE;	    ees[e].kind := EESVAR;	    ees[e].constInt := 0;	end;    end;end;procedure Increment{(value : integer)};begin    { if need to store bit offset, make into address first }    if (opd11 = 'a') and (value mod BYTESIZE <> 0) and	    (ees[top].kind <> EESADDR)    then begin	MakeBaseAddress(top);    end;    case ees[top].kind of	EESDATA : begin	    if opd11 = 'a' then begin		{ value is in bits }		ees[top].constInt := ees[top].constInt + value div BYTESIZE;	    end else begin		ees[top].constInt := ees[top].constInt + value;	    end;	end;	EESVAR : begin	    if ees[top].indirect then begin		Eval(top);	    end;	    if opd11 = 'a' then begin		{ value is in bits }		ees[top].constInt := ees[top].constInt + value div BYTESIZE;	    end else begin		ees[top].constInt := ees[top].constInt + value;	    end;	end;	EESADDR : begin	    if ees[top].indirect then begin		Eval(top);	    end;	    ees[top].addrOffset := ees[top].addrOffset + value;	end;    end;end;procedure SetConst{(size : sizerange; e : EESElement)};const    BITSPERSETWORD = 16;var    value: array [1..MAXSETWORDS] of integer;    word, bit, index: integer;    numbits : integer;    constlab : integer;begin    for word := 1 to MAXSETWORDS do value[word] := 0;    numbits := Int(opd^[3]);    if numbits > MAXSETSIZE then begin	Error('Too many bits in set');    end;    for index:=0 to numbits-1 do begin	if index mod BITSPERSETWORD = 0 then bit := 1 else bit := 2 * bit;	if (opd^[4][index+1]='1') then begin	    value[1+index div BITSPERSETWORD] :=			value[1+index div BITSPERSETWORD] + bit;	end;    end;    constlab := currentConstant;    currentConstant := currentConstant + 1;    Op('.data'); I(1); L;    C('k'); I(constlab); C(':'); L;    for word:=1 to (size+BITSPERSETWORD-1) div BITSPERSETWORD do begin	Op('.word'); I(value[word]); L;    end;    Op('.text'); L;    ees[e].addrMemType := 'k';    ees[e].addrBlock := constlab;end;{ TwoOrThree:    if dest is data and not constant, use 2 operand form	op2  source,dest    if not, allocate reg, use 3 operand form, and make dest data	op3  source,dest,r}procedure TwoOrThree{(op:ShortString; source, dest : EESElement; ptype : pcodetype; size : sizerange)};var    r : Reg;    i : integer;    nsize : sizerange;    dostore : boolean;begin    i := 1;    while op[i] <> 'N' do begin	i := i + 1;    end;    Check(source,size);    Check(dest,size);    if (ees[dest].kind = EESDATA) and ActiveReg(ees[dest].dreg) then begin	op[i] := '2';	Op(op); Opnd(source); X; Opnd(dest); L;    end else begin	dostore := false;	{ look ahead to see if next thing is a store }	if nopcode in [opstr, opsro, opstn] then begin	    { size must match, to avoid complications }	    nsize := Int(nopd^[2]);	    if nsize = size then begin		dostore := true;	    end;	end;	if dostore then begin	    { make store be current instruction }	    Advance;	    PreRead;	    Push(EESVAR);	    ees[top].size := size;	    ees[top].ptype := ptype;	    { get address }	    if opcode = opsro then begin		ees[top].addrLevel := 0;		ees[top].addrMemType := opd^[3][1];		ees[top].addrOffset := Int(opd^[4]);		ees[top].addrBlock := Int(opd^[5]);	    end else if opcode in [opstr,opstn] then begin		ees[top].addrLevel := curlev - Int(opd^[3]);		ees[top].addrMemType := opd^[4][1];		ees[top].addrOffset := Int(opd^[5]);		ees[top].addrBlock := Int(opd^[6]);	    end else begin		Error('TwoOrThree: store is not str or sro');	    end;	    Check(top,size);	    op[i] := '3';	    Op(op); Opnd(source); X; Opnd(dest); X; Opnd(top); L;	    if opcode = opstn then begin		{ as in stn: pop original and leave T on stack }		SwapEES(dest,top);		Pop(1);	    end else begin		Pop(2);	{ as in store: one for the result, one for the address }	    end;	end else begin	    r := AllocReg(REGEES,dest,ptype);	    op[i] := '3';	    Op(op); Opnd(source); X; Opnd(dest); X; R(r); L;	    FreeReg(ees[dest].breg);	    FreeReg(ees[dest].sreg);	    ClearAddress(dest);	    ees[dest].kind := EESDATA;	    ees[dest].size := size;	    ees[dest].ptype := ptype;	    ees[dest].dreg := r;	    ees[dest].constInt := 0;	end;    end;end;procedure PushConst{(ptype:pcodetype; size:sizerange;value:integer)};begin    Push(EESDATA);    ees[top].ptype := ptype;    ees[top].size := size;    ees[top].constInt := value;end;procedure PushReg{(ptype:pcodetype; size:sizerange;dreg:Reg)};begin    Push(EESDATA);    ees[top].ptype := ptype;    ees[top].size := size;    ees[top].dreg := dreg;end;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -