Răsfoiți Sursa

first 256 bit vector instructions are working.
Example:
MOV EAX, [EBP+a];
VMOVUPS YMM0, [EAX]
VADDPS YMM0, YMM0, YMM0
VMOVUPS [EAX], YMM0
Instructions are all entered and in place but some encodings are not yet filled. Missing instructions will raise an exception in the compiler.

git-svn-id: https://svn.inf.ethz.ch/svn/lecturers/a2/trunk@7550 8c9fc860-2736-0410-a75d-ab315db34111

felixf 7 ani în urmă
părinte
comite
c711e11f5a
2 a modificat fișierele cu 180 adăugiri și 112 ștergeri
  1. 41 7
      source/FoxAMD64Assembler.Mod
  2. 139 105
      source/FoxAMD64InstructionSet.Mod

+ 41 - 7
source/FoxAMD64Assembler.Mod

@@ -1,5 +1,5 @@
 MODULE FoxAMD64Assembler; (**  AUTHOR "fn & fof"; PURPOSE "Oberon Compiler:AMD 64 Assembler";  **)
-(* (c) fof ETH Zürich, 2008 *)
+(* (c) fof ETH Zürich, 2008-2017 *)
 (*
 	this module has in great portions been taken over  from Florian Negele's PCAAMD64.Mod
 *)
@@ -56,6 +56,7 @@ CONST
 	bits32* = 4;
 	bits64* = 8;
 	bits128* = 16;
+	bits256* = 32;
 
 	(** constants from InstructionSet **)
 	(* instruction encoding *)
@@ -66,6 +67,9 @@ CONST
 	rb= InstructionSet.rb; rw= InstructionSet.rw; rd= InstructionSet.rd; rq= InstructionSet.rq;
 	mem64Operand= InstructionSet.mem64Operand; mem128Operand= InstructionSet.mem128Operand;
 	fpStackOperand= InstructionSet.fpStackOperand; directMemoryOffset= InstructionSet.directMemoryOffset;
+	RXB = InstructionSet.RXB;
+	Src1Prefix = InstructionSet.Src1Prefix;
+	
 	(* limits *)
 	maxNumberOperands = InstructionSet.maxNumberOperands;
 
@@ -79,6 +83,7 @@ CONST
 	segReg*= InstructionSet.segReg;
 	mmx*= InstructionSet.mmx;
 	xmm*= InstructionSet.xmm;
+	ymm*= InstructionSet.ymm;
 	mem*=InstructionSet.mem;
 	sti*= InstructionSet.sti;
 	imm*= InstructionSet.imm;
@@ -338,7 +343,7 @@ TYPE
 			BEGIN
 				FOR i := 0 TO maxNumberOperands -1 DO
 					CASE InstructionSet.instructions[instr].operands[i] OF
-					InstructionSet.reg8, InstructionSet.reg16, InstructionSet.reg32, InstructionSet.reg64, InstructionSet.xmm, InstructionSet.mmx: RETURN i;
+					InstructionSet.reg8, InstructionSet.reg16, InstructionSet.reg32, InstructionSet.reg64, InstructionSet.xmm, InstructionSet.mmx, InstructionSet.ymm: RETURN i;
 					ELSE
 					END;
 				END;
@@ -354,6 +359,7 @@ TYPE
 					InstructionSet.mem8, InstructionSet.mem16, InstructionSet.mem32, InstructionSet.mem64, InstructionSet.mem128,
 					InstructionSet.regmem8, InstructionSet.regmem16, InstructionSet.regmem32, InstructionSet.regmem64,
 					InstructionSet.mmxmem32, InstructionSet.mmxmem64,
+					InstructionSet.ymmmem128, InstructionSet.ymmmem256,
 					InstructionSet.xmmmem32, InstructionSet.xmmmem64, InstructionSet.xmmmem128:
 						RETURN i;
 					ELSE
@@ -367,7 +373,7 @@ TYPE
 			BEGIN
 				FOR i := 0 TO maxNumberOperands -1 DO
 					CASE InstructionSet.instructions[instr].operands[i] OF
-					InstructionSet.segReg, InstructionSet.mmx, InstructionSet.xmm, InstructionSet.CRn, InstructionSet.DRn:
+					InstructionSet.segReg, InstructionSet.mmx, InstructionSet.xmm, InstructionSet.ymm, InstructionSet.CRn, InstructionSet.DRn:
 						RETURN i;
 					ELSE
 					END;
@@ -406,6 +412,9 @@ TYPE
 
 			instr := FindInstruction(mnem,operands);
 			IF instr = none THEN RETURN FALSE END;
+			IF Trace THEN
+				KernelLog.String("instr = "); KernelLog.Int(instr,1); KernelLog.Ln;
+			END;
 			bitwidthOptions := InstructionSet.instructions[instr].bitwidthOptions;
 			FOR i := 0 TO InstructionSet.maxCodeLength-1 DO opcode[i] := InstructionSet.instructions[instr].code[i] END;
 
@@ -950,6 +959,21 @@ TYPE
 						END;
 					| mem64Operand, mem128Operand: (* ignored *)
 						IF Trace THEN KernelLog.String(" mem64/mem128 "); END;
+					| RXB: 
+						IF val # -1 THEN code.PutByte (val); val := -1 END;
+						IF Trace THEN KernelLog.String(" RXB ");  TRACE(rexPrefix) END;
+						INC(oppos); 
+						byte := ORD(opcode[oppos]);
+						IF ~(rexB IN rexPrefix) THEN byte := byte + 80H END;
+						IF ~(rexX IN rexPrefix) THEN byte := byte + 40H END;
+						IF ~(rexR IN rexPrefix) THEN byte := byte + 20H END;
+						code.PutByte(byte); 
+					| Src1Prefix:
+						IF val # -1 THEN code.PutByte (val); val := -1 END;
+						IF Trace THEN KernelLog.String(" Src1Prefix "); END;
+						INC(oppos);
+						ASSERT((operands[1].type = xmm) OR (operands[1].type = ymm)); 
+						code.PutByte(ORD(opcode[oppos])+(0FH -InstructionSet.RegisterIndex(operands[1].register))*0x08);
 					ELSE HALT(100) (* decoding error *)
 					END;
 				END;
@@ -2186,7 +2210,7 @@ TYPE
 
 	PROCEDURE IsRegisterOperand*(CONST op: Operand): BOOLEAN;
 	BEGIN
-		RETURN op.type IN {reg8, reg16, reg32, reg64, CRn, DRn, segReg, sti, mmx, xmm}
+		RETURN op.type IN {reg8, reg16, reg32, reg64, CRn, DRn, segReg, sti, mmx, xmm, ymm}
 	END IsRegisterOperand;
 
 	PROCEDURE IsMemoryOperand*(CONST op: Operand): BOOLEAN;
@@ -2209,6 +2233,7 @@ TYPE
 			|segReg: w.String("segReg");
 			|mmx: w.String("mmx");
 			|xmm: w.String("xmm");
+			|ymm: w.String("ymm");
 			|mem: w.String("mem");
 			|sti: w.String("sti");
 			|imm: w.String("imm");
@@ -2223,7 +2248,7 @@ TYPE
 	PROCEDURE DumpOperand*(w: Streams.Writer; CONST operand: Operand);
 	BEGIN
 		CASE operand.type OF
-		|reg8, reg16, reg32, reg64, CRn, DRn, segReg, sti, mmx, xmm:
+		|reg8, reg16, reg32, reg64, CRn, DRn, segReg, sti, mmx, xmm, ymm:
 			w.String(InstructionSet.registers[operand.register].name);
 		|mem:
 			IF operand.sizeInBytes = 1 THEN w.String("BYTE ")
@@ -2392,6 +2417,13 @@ TYPE
 			ELSE
 				RETURN FALSE;
 			END
+		|ymm:
+			CASE type OF
+			InstructionSet.ymm, InstructionSet.ymmmem128, InstructionSet.ymmmem256:
+				RETURN TRUE;
+			ELSE
+				RETURN FALSE;
+			END
 		|mem:
 			CASE type OF
 			| InstructionSet.mem:
@@ -2414,8 +2446,10 @@ TYPE
 				RETURN ((operand.sizeInBytes = bitsDefault) OR (operand.sizeInBytes = bits64)) & ((operand.register= none) OR (IsMemReg(operand.register)));
 			| InstructionSet.mem128:
 				RETURN (operand.sizeInBytes = bitsDefault) OR (operand.sizeInBytes = bits128);
-			| InstructionSet.xmmmem128:
+			| InstructionSet.xmmmem128, InstructionSet.ymmmem128:
 				RETURN ((operand.sizeInBytes = bitsDefault) OR (operand.sizeInBytes = bits128)) & ((operand.register= none) OR (IsMemReg(operand.register)));
+			| InstructionSet.ymmmem256:
+				RETURN ((operand.sizeInBytes = bitsDefault) OR (operand.sizeInBytes = bits256)) & ((operand.register= none) OR (IsMemReg(operand.register)));
 			| InstructionSet.moffset8:
 				RETURN ((operand.sizeInBytes = bitsDefault) OR (operand.sizeInBytes = bits8)) & (operand.register= none);
 			| InstructionSet.moffset16:
@@ -2504,7 +2538,7 @@ TYPE
 		operand.type := InstructionSet.RegisterType(register);
 		operand.register :=register;
 		CASE operand.type OF
-			reg8,reg16,reg32,reg64,segReg,CRn,DRn,sti,xmm,mmx: (* ok *)
+			reg8,reg16,reg32,reg64,segReg,CRn,DRn,sti,xmm,mmx,ymm: (* ok *)
 			|InstructionSet.st0: operand.type := InstructionSet.sti;
 		ELSE
 			HALT(100);

+ 139 - 105
source/FoxAMD64InstructionSet.Mod

@@ -93,10 +93,10 @@ CONST
 
 
 	(*
-		OCProgTools.Enum -l=1 -e
+		FoxProgTools.Enum -l=1 -e
 		(** operand types, numbers assigned to the types do not have a special meaning **)
 		(* register classes first *)
-		 reg8 reg16 reg32 reg64 CRn DRn segReg mmx xmm sti
+		 reg8 reg16 reg32 reg64 CRn DRn segReg mmx xmm ymm sti
 		 (* other classes *)
 		 mem imm ioffset pntr1616 pntr1632
 		(* special registers *)
@@ -105,103 +105,113 @@ CONST
 		 imm16  imm32  imm64  imm8
 		 uimm16  uimm32  uimm8
 		 simm16  simm32  simm8
-		 mem128  mem16  mem32  mem64  mem8
+		mem256
+ 		mem128  mem16  mem32  mem64  mem8
 		 moffset16  moffset32  moffset64  moffset8
 		 rel16off  rel32off  rel8off
 		(* ambivalent operand types *)
-		 regmem16  regmem32  regmem64  regmem8
+		 reg3264
+		 regmem16  regmem32  regmem64  regmem8 reg32mem16
 		 mmxmem32  mmxmem64
-		 xmmmem128  xmmmem32  xmmmem64
+		 xmmmem256 xmmmem128  xmmmem32  xmmmem64
+		xmmmem8
+		xmmmem16
+		ymmmem128
+		ymmmem256
 		(* miscellaneous *)
 		 one three
+		vm32x
+		vm32y
+		vm64x
+		vm64y
+		m2z;
 		 ~
 	*)
 	(** operand types, numbers assigned to the types do not have a special meaning **)
 	(* register classes first *)
-	reg8*= 0; (* GPR 8 *)
-	reg16*= 1; (* GPR 16 *)
-	reg32*= 2; (* GPR 32 *)
-	reg64*= 3; (* GPR 64 *)
-	CRn*= 4; (* counter registers *)
-	DRn*= 5; (* debug registers *)
-	segReg*= 6; (* segment registers *)
-	mmx*= 7; (* 64bit mmx registers *)
-	xmm*= 8; (* 128bit sse registers *)
-	sti*= 9; (* floating point registers *)
+	reg8*= 0; 
+	reg16*= 1; 
+	reg32*= 2; 
+	reg64*= 3; 
+	CRn*= 4; 
+	DRn*= 5; 
+	segReg*= 6; 
+	mmx*= 7; 
+	xmm*= 8; 
+	ymm*= 9; 
+	sti*= 10; 
 	(* other classes *)
-	mem*= 10; (* memory operands *)
-	imm*= 11; (* immediate operands *)
-	ioffset*= 12; (* used for MOV AL/AX/EAX/RAX   *)
-	pntr1616*= 13;  (* used for far jumps and calls*)
-	pntr1632*= 14;  (* used for far jumps and calls *)
+	mem*= 11; 
+	imm*= 12; 
+	ioffset*= 13; 
+	pntr1616*= 14; 
+	pntr1632*= 15; 
 	(* special registers *)
-	AL*= 15;
-	AX*= 16;
-	CL*= 17;
-	CR8*= 18;
-	CS*= 19;
-	DS*= 20;
-	DX*= 21;
-	EAX*= 22;
-	ECX*= 23;
-	ES*= 24;
-	FS*= 25;
-	GS*= 26;
-	RAX*= 27;
-	SS*= 28;
-	rAX*= 29;
-	st0*= 30;
+	AL*= 16; 
+	AX*= 17; 
+	CL*= 18; 
+	CR8*= 19; 
+	CS*= 20; 
+	DS*= 21; 
+	DX*= 22; 
+	EAX*= 23; 
+	ECX*= 24; 
+	ES*= 25; 
+	FS*= 26; 
+	GS*= 27; 
+	RAX*= 28; 
+	SS*= 29; 
+	rAX*= 30; 
+	st0*= 31; 
 	(* immediates and memory locations *)
-	imm16*= 31;
-	imm32*= 32;
-	imm64*= 33;
-	imm8*= 34;
-	uimm16*= 35;
-	uimm32*= 36;
-	uimm8*= 37;
-	simm16*= 38;
-	simm32*= 39;
-	simm8*= 40;
-	mem128*= 41;
-	mem16*= 42;
-	mem32*= 43;
-	mem64*= 44;
-	mem8*= 45;
-	moffset16*= 46;
-	moffset32*= 47;
-	moffset64*= 48;
-	moffset8*= 49;
-	rel16off*= 50;
-	rel32off*= 51;
-	rel8off*= 52;
+	imm16*= 32; 
+	imm32*= 33; 
+	imm64*= 34; 
+	imm8*= 35; 
+	uimm16*= 36; 
+	uimm32*= 37; 
+	uimm8*= 38; 
+	simm16*= 39; 
+	simm32*= 40; 
+	simm8*= 41; 
+	mem256*= 42; 
+	mem128*= 43; 
+	mem16*= 44; 
+	mem32*= 45; 
+	mem64*= 46; 
+	mem8*= 47; 
+	moffset16*= 48; 
+	moffset32*= 49; 
+	moffset64*= 50; 
+	moffset8*= 51; 
+	rel16off*= 52; 
+	rel32off*= 53; 
+	rel8off*= 54; 
 	(* ambivalent operand types *)
-	regmem16*= 53;
-	regmem32*= 54;
-	regmem64*= 55;
-	regmem8*= 56;
-	mmxmem32*= 57;
-	mmxmem64*= 58;
-	xmmmem128*= 59;
-	xmmmem32*= 60;
-	xmmmem64*= 61;
+	reg3264*= 55; 
+	regmem16*= 56; 
+	regmem32*= 57; 
+	regmem64*= 58; 
+	regmem8*= 59; 
+	reg32mem16*= 60; 
+	mmxmem32*= 61; 
+	mmxmem64*= 62; 
+	xmmmem256*= 63; 
+	xmmmem128*= 64; 
+	xmmmem32*= 65; 
+	xmmmem64*= 66; 
+	xmmmem8*= 67; 
+	xmmmem16*= 68; 
+	ymmmem128*= 69; 
+	ymmmem256*= 70; 
 	(* miscellaneous *)
-	one*= 62;
-	three*= 63;
-
-	ymm *= 64;
-	ymmmem128*=65;
-	ymmmem256*=66;
-	vm32x*=67;
-	vm32y*=68;
-	vm64x*=69;
-	vm64y*=70;
-	mem256*= 71;
-	xmmmem256*=72;
-	reg3264*=73;
-	xmmmem8*=74;
-	xmmmem16*=75;
-	reg32mem16*=76;
-	m2z*=77;
+	one*= 71; 
+	three*= 72; 
+	vm32x*= 73; 
+	vm32y*= 74; 
+	vm64x*= 75; 
+	vm64y*= 76; 
+	m2z*= 77; 
 
 	(** prefixes **)
 	prfOP* = 066H;
@@ -306,15 +316,18 @@ CONST
 	regR8*= 104; regR9*= 105; regR10*= 106; regR11*= 107; regR12*= 108; regR13*= 109; regR14*= 110; regR15*= 111;
 	regRIP*= 112;
 	(** other registers **)
-	regES*= 128; regCS*= 129; regSS*= 130; regDS*= 131; regFS*= 132; regGS*= 133; regCR0*= 134; regCR1*= 135;
-	regCR2*= 136; regCR3*= 137; regCR4*= 138; regCR5*= 139; regCR6*= 140; regCR7*= 141; regCR8*= 142; regCR9*= 143;
-	regCR10*= 144; regCR11*= 145; regCR12*= 146; regCR13*= 147; regCR14*= 148; regCR15*= 149; regDR0*= 150; regDR1*= 151;
-	regDR2*= 152; regDR3*= 153; regDR4*= 154; regDR5*= 155; regDR6*= 156; regDR7*= 157; regDR8*= 158; regDR9*= 159;
-	regDR10*= 160; regDR11*= 161; regDR12*= 162; regDR13*= 163; regDR14*= 164; regDR15*= 165; regST0*= 166; regST1*= 167;
-	regST2*= 168; regST3*= 169; regST4*= 170; regST5*= 171; regST6*= 172; regST7*= 173; regXMM0*= 174; regXMM1*= 175;
-	regXMM2*= 176; regXMM3*= 177; regXMM4*= 178; regXMM5*= 179; regXMM6*= 180; regXMM7*= 181; regXMM8*= 182; regXMM9*= 183;
-	regXMM10*= 184; regXMM11*= 185; regXMM12*= 186; regXMM13*= 187; regXMM14*= 188; regXMM15*= 189; regMMX0*= 190; regMMX1*= 191;
-	regMMX2*= 192; regMMX3*= 193; regMMX4*= 194; regMMX5*= 195; regMMX6*= 196; regMMX7*= 197; numberRegisters*= 198;
+	regES*= 128; regCS*= 129; regSS*= 130; regDS*= 131; regFS*= 132; regGS*= 133; regCR0*= 134; regCR1*= 135; 
+	regCR2*= 136; regCR3*= 137; regCR4*= 138; regCR5*= 139; regCR6*= 140; regCR7*= 141; regCR8*= 142; regCR9*= 143; 
+	regCR10*= 144; regCR11*= 145; regCR12*= 146; regCR13*= 147; regCR14*= 148; regCR15*= 149; regDR0*= 150; regDR1*= 151; 
+	regDR2*= 152; regDR3*= 153; regDR4*= 154; regDR5*= 155; regDR6*= 156; regDR7*= 157; regDR8*= 158; regDR9*= 159; 
+	regDR10*= 160; regDR11*= 161; regDR12*= 162; regDR13*= 163; regDR14*= 164; regDR15*= 165; regST0*= 166; regST1*= 167; 
+	regST2*= 168; regST3*= 169; regST4*= 170; regST5*= 171; regST6*= 172; regST7*= 173; regXMM0*= 174; regXMM1*= 175; 
+	regXMM2*= 176; regXMM3*= 177; regXMM4*= 178; regXMM5*= 179; regXMM6*= 180; regXMM7*= 181; regXMM8*= 182; regXMM9*= 183; 
+	regXMM10*= 184; regXMM11*= 185; regXMM12*= 186; regXMM13*= 187; regXMM14*= 188; regXMM15*= 189; regMMX0*= 190; regMMX1*= 191; 
+	regMMX2*= 192; regMMX3*= 193; regMMX4*= 194; regMMX5*= 195; regMMX6*= 196; regMMX7*= 197; regYMM0*= 198; regYMM1*= 199; 
+	regYMM2*= 200; regYMM3*= 201; regYMM4*= 202; regYMM5*= 203; regYMM6*= 204; regYMM7*= 205; regYMM8*= 206; regYMM9*= 207; 
+	regYMM10*= 208; regYMM11*= 209; regYMM12*= 210; regYMM13*= 211; regYMM14*= 212; regYMM15*= 213; 
+	numberRegisters*= 214; 
 
 VAR 
 	opAAA*,
@@ -1760,11 +1773,13 @@ VAR
 							INC(i); ASSERT(cdc[i] ="n");
 							INC(i); ASSERT(cdc[i] ="t");
 							code[k] := CHR(CountPrefix);
+							mul := mul DIV 10H;
 						ELSIF cdc[i] = "d" THEN
 							INC(i); ASSERT(cdc[i] ="e"); 
 							INC(i); ASSERT(cdc[i] ="s");
 							INC(i); ASSERT(cdc[i] ="t");
 							code[k] := CHR(DestPrefix);
+							mul := mul DIV 10H;
 						ELSIF cdc[i] = "s" THEN
 							INC(i); ASSERT(cdc[i] ="r"); 
 							INC(i); ASSERT(cdc[i] ="c");
@@ -1776,6 +1791,7 @@ VAR
 								code[k] := CHR(Src2Prefix);
 								INC(i);
 							END;
+							mul := mul DIV 10H;
 						ELSE HALT(100);
 						END;
 						INC(i);
@@ -5427,6 +5443,23 @@ VAR
 		AddRegister (regXMM14,"XMM14", xmm, bits64, 14);
 		AddRegister (regXMM15,"XMM15", xmm, bits64, 15);
 
+		AddRegister (regYMM0,"YMM0", ymm, bits64, 0);
+		AddRegister (regYMM1,"YMM1", ymm, bits64, 1);
+		AddRegister (regYMM2,"YMM2", ymm, bits64, 2);
+		AddRegister (regYMM3,"YMM3", ymm, bits64, 3);
+		AddRegister (regYMM4,"YMM4", ymm, bits64, 4);
+		AddRegister (regYMM5,"YMM5", ymm, bits64, 5);
+		AddRegister (regYMM6,"YMM6", ymm, bits64, 6);
+		AddRegister (regYMM7,"YMM7", ymm, bits64, 7);
+		AddRegister (regYMM8,"YMM8", ymm, bits64, 8);
+		AddRegister (regYMM9,"YMM9", ymm, bits64, 9);
+		AddRegister (regYMM10,"YMM10", ymm, bits64, 10);
+		AddRegister (regYMM11,"YMM11", ymm, bits64, 11);
+		AddRegister (regYMM12,"YMM12", ymm, bits64, 12);
+		AddRegister (regYMM13,"YMM13", ymm, bits64, 13);
+		AddRegister (regYMM14,"YMM14", ymm, bits64, 14);
+		AddRegister (regYMM15,"YMM15", ymm, bits64, 15);
+
 		AddRegister (regMMX0,"MMX0", mmx, bits128, 0);
 		AddRegister (regMMX1,"MMX1", mmx, bits128, 1);
 		AddRegister (regMMX2,"MMX2", mmx, bits128, 2);
@@ -5480,20 +5513,21 @@ VAR
 	END InitCPUs;
 
 	PROCEDURE Trace*;
-	VAR instr: LONGINT; i: LONGINT;
+	VAR instr,mnem: LONGINT; i: LONGINT;
 	BEGIN
-		instr := 0;
-		WHILE instr < numberInstructions DO
-			KernelLog.Int(instr,5);
-			KernelLog.String(" ");
-			FOR i := 0 TO maxCodeLength-1 DO
-				KernelLog.Hex(ORD(instructions[instr].code[i]),-2); KernelLog.String(" ");
-			END;
-			FOR i := 0 TO maxNumberOperands-1 DO
-				KernelLog.Int(instructions[instr].operands[i],1); KernelLog.String(" ");
+		FOR mnem := 0 TO numberMnemonics-1 DO
+			KernelLog.String(mnemonics[mnem].name); KernelLog.Ln;
+			FOR instr := mnemonics[mnem].firstInstruction TO mnemonics[mnem].lastInstruction DO
+				KernelLog.Int(instr,5);
+				KernelLog.String(" ");
+				FOR i := 0 TO maxCodeLength-1 DO
+					KernelLog.Hex(ORD(instructions[instr].code[i]),-2); KernelLog.String(" ");
+				END;
+				FOR i := 0 TO maxNumberOperands-1 DO
+					KernelLog.Int(instructions[instr].operands[i],1); KernelLog.String(" ");
+				END;
+				KernelLog.Ln;
 			END;
-			KernelLog.Ln;
-			INC(instr);
 		END;
 	END Trace;