Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- program test;
- type
- pchar = ^char;
- type
- TAxiRPort = record
- AR: TOutPort;
- R: TInPort;
- end;
- TAxiPort = record
- AR: TOutPort;
- R: TInPort;
- AW,
- W: TOutPort;
- B: TInPort;
- end;
- function GetAxiR(A,D: ptrint): TAxiRPort;
- begin
- GetAxiR.AR:=GetOutPort(A);
- GetAxiR.R:=GetInPort(D);
- end;
- function GetAxi(A,D: ptrint): TAxiPort;
- begin
- GetAxi.AR:=GetOutPort(A);
- GetAxi.R:=GetInPort(D);
- GetAxi.AW:=GetOutPort(A);
- GetAxi.W:=GetOutPort(D);
- GetAxi.B:=GetInPort(2);
- end;
- var
- IPort: TAxiRPort;
- DPort: TAxiPort;
- Regs: TMemory;
- PC: TRegister;
- function ReadData(var APort: TAxiRPort; AAddr: ptrint): ptrint;
- begin
- _Write(APort.AR, AAddr);
- ReadData:=_Read(APort.R);
- end;
- procedure WriteB(var APort: TAxiPort; AAddr, AValue: ptrint);
- begin
- _Write(APort.AW, AAddr);
- _Write(APort.W, AValue);
- _Read(APort.B);
- end;
- procedure WriteH(var APort: TAxiPort; AAddr, AValue: ptrint);
- begin
- _Write(APort.AW, AAddr);
- _Write(APort.W, AValue);
- _Read(APort.B);
- end;
- procedure WriteW(var APort: TAxiPort; AAddr, AValue: ptrint);
- begin
- _Write(APort.AW, AAddr);
- _Write(APort.W, AValue);
- _Read(APort.B);
- end;
- procedure WriteQ(var APort: TAxiPort; AAddr, AValue: ptrint);
- begin
- _Write(APort.AW, AAddr);
- _Write(APort.W, AValue);
- _Read(APort.B);
- end;
- function ReadB(var APort: TAxiPort; AAddr: ptrint): ptrint;
- begin
- _Write(APort.AR, AAddr);
- ReadB:=_Read(APort.R);
- end;
- function ReadH(var APort: TAxiPort; AAddr: ptrint): ptrint;
- begin
- _Write(APort.AR, AAddr);
- ReadH:=_Read(APort.R);
- end;
- function ReadW(var APort: TAxiPort; AAddr: ptrint): ptrint;
- begin
- _Write(APort.AR, AAddr);
- ReadW:=_Read(APort.R);
- end;
- function ReadQ(var APort: TAxiPort; AAddr: ptrint): ptrint;
- begin
- _Write(APort.AR, AAddr);
- ReadQ:=_Read(APort.R);
- end;
- const
- OP_LUI = $37;
- OP_AUIPC = $17;
- OP_JAL = $6F;
- OP_JALR = $67;
- OP_BEQ = $63;
- OP_LB = $03;
- OP_SB = $23;
- OP_ADDI = $13;
- OP_ADD = $33;
- OP_ADDI32 = $1B;
- OP_ADD32 = $3B;
- OP_FENCE = $0F;
- OP_ECALL = $73;
- function SarInt64(a,b: int64): int64; assembler;
- asm
- sra a1, a1, a2
- end;
- function Extr(A,lsb,msb: ptrint): ptrint;
- begin
- Extr:=(a shr lsb) and ((1 shl (msb-lsb+1))-1);
- end;
- function SExt(A,msb: ptrint): ptrint;
- begin
- if msb>=63 then
- SExt:=a
- else
- SExt:=SarInt64(A shl (63-msb), 63-msb);
- end;
- function ESExt(A: ptrint; msb: ptrint): ptrint;
- begin
- if msb>=63 then
- ESExt:=a
- else
- ESExt:=SarInt64(A shl (63-msb), 63-msb);
- end;
- const
- IllegalOpcodeAddr = 0;
- procedure Execute;
- var
- NPC, op, aaddr, imm, rd, rs1, rs2, f3, f7: ptrint;
- tmp, a1, a2, a3, a4: ptrint;
- result, va, vb, x: ptrint;
- begin
- AAddr:=Load(PC);
- op:=ReadData(IPort, AAddr);
- NPC:=AAddr+4;
- case op and $7F of
- OP_LUI,
- OP_AUIPC:
- begin
- // U
- imm:=SExt(Extr(op,12,31) shl 12, 31);
- rd:=extr(op,7,11);
- if rd>0 then
- begin
- if (op and $7F)=OP_LUI then
- Store(regs,rd,imm)
- else
- Store(regs,rd,AAddr+imm);
- end;
- end;
- OP_JAL:
- begin
- // UJ
- imm:=SExt((Extr(op,21,30) shl 1) or
- (Extr(op,20,20) shl 11) or
- (Extr(op,12,19) shl 12) or
- (Extr(op,31,31) shl 20),20);
- rd:=extr(op,7,11);
- if rd>0 then Store(Regs,rd,AAddr+4);
- NPC:=AAddr+imm;
- end;
- OP_SB:
- begin
- // S
- imm:=SExt((Extr(op,7,11) shl 0) or
- (Extr(op,25,31) shl 5), 11);
- rs1:=Extr(op,15,19);
- rs2:=Extr(op,20,24);
- f3:=Extr(op,12,14);
- if f3=0 then WriteB(DPort, (load(regs,rs1)+imm), (load(regs,rs2))) else
- if f3=1 then WriteH(DPort, (load(regs,rs1)+imm), (load(regs,rs2))) else
- if f3=2 then WriteW(DPort, (load(regs,rs1)+imm), (load(regs,rs2))) else
- if f3=3 then WriteQ(DPort, (load(regs,rs1)+imm), (load(regs,rs2))) else
- NPC:=IllegalOpcodeAddr;
- end;
- OP_BEQ:
- begin
- // SB
- imm:=sext((extr(op,7,7) shl 11) or
- (extr(op,8,11) shl 1) or
- (extr(op,25,30) shl 5) or
- (extr(op,31,31) shl 12),12);
- rs1:=Extr(op,15,19);
- rs2:=Extr(op,20,24);
- f3:=Extr(op,12,14);
- va:=load(regs,rs1);
- vb:=load(regs,rs2);
- if f3=0 then result:=ord(va=vb) else
- if f3=1 then result:=ord(va<>vb) else
- if f3=4 then result:=ord(va<vb) else
- if f3=5 then result:=ord(vb<=va) else
- if f3=6 then result:=ord(qword(va)<qword(vb)) else
- if f3=7 then result:=ord(qword(vb)<=qword(va)) else
- begin
- NPC:=IllegalOpcodeAddr;
- end;
- if (result<>0) and (f3<>2) and (f3<>3) then
- NPC:=AAddr+imm;
- end;
- OP_JALR:
- begin
- imm:=SExt(Extr(op,20,31), 11);
- rs1:=Extr(op,15,19);
- rd:=extr(op,7,11);
- if rd>0 then store(regs,rd,npc);
- NPC:=load(regs,rs1)+imm;
- end;
- OP_LB:
- begin
- imm:=SExt(Extr(op,20,31), 11);
- rs1:=Extr(op,15,19);
- rd:=extr(op,7,11);
- f3:=Extr(op,12,14);
- if rd>0 then
- begin
- if f3=0 then store(regs,rd,ESExt(ReadB(DPort, (load(regs,rs1)+imm)),7)) else
- if f3=1 then store(regs,rd,ESExt(ReadH(DPort, (load(regs,rs1)+imm)),15)) else
- if f3=2 then store(regs,rd,ESExt(ReadW(DPort, (load(regs,rs1)+imm)),31)) else
- if f3=3 then store(regs,rd,ReadQ(DPort, (load(regs,rs1)+imm))) else
- if f3=4 then store(regs,rd,ReadB(DPort, (load(regs,rs1)+imm))) else
- if f3=5 then store(regs,rd,ReadH(DPort, (load(regs,rs1)+imm))) else
- if f3=6 then store(regs,rd,ReadW(DPort, (load(regs,rs1)+imm))) else
- begin
- NPC:=IllegalOpcodeAddr;
- end;
- end;
- end;
- OP_ADDI,
- OP_ADDI32:
- begin
- // I
- rs1:=Extr(op,15,19);
- imm:=SExt(Extr(op,20,31), 11);
- rd:=extr(op,7,11);
- f3:=Extr(op,12,14);
- f7:=Extr(op,25,31);
- va:=load(regs,rs1);
- vb:=(imm);
- if (op and $7F)=OP_ADDI32 then
- begin
- va:=ESExt(va,31);
- vb:=ESExt(vb,31);
- end;
- if f3=0 then result:=va+vb else
- if f3=1 then result:=va shl vb else
- if f3=2 then result:=ord(va < vb) else
- if f3=3 then result:=ord(qword(va)<qword(vb)) else
- if f3=4 then result:=va xor vb else
- if f3=5 then
- begin
- if (f7 and $20)=$20 then
- result:=sarint64(va,vb)
- else
- result:=va shr vb;
- end else
- if f3=6 then result:=va or vb else
- result:=va and vb;
- if (op and $7F)=OP_ADDI32 then
- result:=ESExt(result,31);
- if rd>0 then store(regs,rd,(result));
- end;
- OP_FENCE,
- OP_ECALL:
- begin
- end;
- OP_ADD,
- OP_ADD32:
- begin
- // R
- rs1:=Extr(op,15,19);
- rs2:=Extr(op,20,24);
- rd:=extr(op,7,11);
- f3:=Extr(op,12,14);
- f7:=Extr(op,25,31);
- va:=load(regs,rs1);
- vb:=load(regs,rs2);
- if (op and $7F)=OP_ADD32 then
- begin
- va:=ESExt(va,31);
- vb:=ESExt(vb,31);
- end;
- if f3=0 then
- begin
- if f7=$20 then
- result:=va-vb
- else
- result:=va+vb;
- end else
- if f3=1 then result:=va shl vb else
- if f3=2 then result:=ord(va < vb) else
- if f3=3 then result:=ord(qword(va)<qword(vb)) else
- if f3=4 then result:=va xor vb else
- if f3=5 then
- begin
- if (f7 and $20)=$20 then
- result:=sarint64(va,vb)
- else
- result:=va shr vb;
- end else
- if f3=6 then result:=va or vb else
- result:=va and vb;
- if (op and $7F)=OP_ADD32 then
- result:=ESExt(result,31);
- if rd>0 then store(regs,rd,result);
- end;
- else
- NPC:=IllegalOpcodeAddr;
- end;
- Store(PC,NPC);
- end;
- begin
- IPort:=GetAxiR(64,32);
- DPort:=GetAxi(64,32);
- PC:=GetRegister(64);
- Regs:=GetMemory(64,32,2,1);
- ClockedTask(@Execute);
- end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement