www.pudn.com > x86.rar > sse3Decoder.v, change:2007-12-05,size:12360b


// top module  for  SSE3  decoder 
 
 
//operation  bit  will  start  from  1280 
module sse3Decoder(instructionSeq,operandSize,addressSize, operation, op1Type, op2Type, op1,op2,opSize,escPrefix,operandOverridePrefix,repPrefixF2,repPrefixF3,Enable); 
//  port  declaration 
input 	[127:0]instructionSeq;	 // the instruction sequence 
input	operandSize;		 
input	addressSize; 
input	Enable; 
input   repPrefixF3;	//repeat prefix F3 
input   repPrefixF2; 
input   operandOverridePrefix; 
input   escPrefix; 
 
output	[10:0]operation; 
output	[17:0]op1Type,op2Type; // specify the type of the operands 
output	[31:0]op1,op2; // the two operands 
output	[2:0]opSize; 
 
reg	[10:0]operation; 
reg	[17:0]op1Type,op2Type; 
reg	[2:0]opSize; 
reg	[31:0]op1,op2; 
 
 
// the declartion of  internal  wires  and  registers 
reg  [127:0]instrSeq; 
reg  [7:0] opCode1; 
reg  [7:0] opCode2; 
reg  [7:0] modR_M_Byte; 
reg  [7:0] SIB_Byte; 
reg directionFlag; 
 
 
 
 
reg [17:0] tempOpType; 
reg [31:0] tempOp; 
 
//  the  coding  started 
 
always @(Enable or instructionSeq or escPrefix or repPrefixF2 or repPrefixF3 or operandOverridePrefix or modR_M_Byte or addressSize or directionFlag) 
	begin 
	if(Enable == 1'b1)    // if the fetching of  the  instruction is complete 
		begin 
		op1Type =18'b10_1111_0000_0000_0010;  //destination 
		op2Type =18'b10_1111_0000_0000_0010;  // source 
		op1 = 32'd0; 
		op2 = 32'd0; 
		opSize =3'b010; // default operand size is 32 bit 
		instrSeq[119:0] = instructionSeq[127:8]; 
		opCode1 = instrSeq[7:0];  //higher order byte 
		opCode2 = instrSeq[15:8]; //lower order byte 
		 
		if (escPrefix)		//if escape prefix  is set 
			begin 
				case (opCode1[7:4]) 
 
					4'h0: 
						begin 
							case(opCode2[3:0]) 
								4'h8: 	operation = 11'd1664;	//MONITOR 
								4'h9:	operation = 11'd1665;	//MWAIT 
							endcase	//case(opCode[3:0]) 
						end  //2'h1 
 
					4'h1: 
						begin 
							case(opCode1[3:0]) 
 
								4'h2:	begin 
										if(repPrefixF2) //if rep Prefix F2 is set 
											operation = 11'd1666;	//MOVDDUP 
										else if(repPrefixF3) 
											operation = 11'd1667;	//MOVSLDUP 
 
									end 
								4'h6:	operation = 11'd1668;	//MOVSHDUP 
 
							endcase	//(opCode1[3:0]) 
 
						end	//2'h2 
 
					4'h7:	begin 
							case(opCode1[3:0]) 
 
								4'hC:	begin 
										if(repPrefixF2) //if rep Prefix F2 is set 
											operation = 11'd1669;	//HADDPS 
										else if(operandOverridePrefix) 
											operation = 11'd1670;	//HADDPD 
 
									end 
								4'hD:	begin 
										if(repPrefixF2) //if rep Prefix F3 is set 
											operation = 11'd1671;	//HSUBPD 
										else if(operandOverridePrefix) 
												operation = 11'd1672;	//HSUBPS  
									end 
 
							endcase	//(opCode1[3:0]) 
						end 
 
					4'hD: 
						begin 
							if(repPrefixF2) //if rep Prefix F2 is set 
								operation = 11'd1673;	//ADDSUBPS 
							else if(operandOverridePrefix) 
								operation = 11'd1674;	//ADDSUBPD 
 
								 
						end 
				 
				endcase	//case (opCode1[7:4]) 
			end	//if (escPrefix) 
		/*else		//if (escPrefix)         these instrutions are already decoded in the fpu decoder. 
			begin 
				case(opCode1[3:0]) 
 
					4'hB:	operation = 11'd1675;	//FISTTP 
 
					4'hD:	operation = 11'd1676;	//FISTTP 
 
					4'hF:	operation = 11'd1677;	//FISTTP 
				endcase 
			end*/ 
 
				//decode according  to the  mod  bit of  opcode 
 
			if(opCode2[7:6] ==2'b11)  		//if mod bit is 11  (if both of them are register operands) 
				begin 
					if( opCode1[7:4] != 4'h0 )	//if operation is != implicit operations 
						begin 
						modR_M_Byte = opCode2; 
							op1Type =18'b10_1111_0000_0000_0010;  //destination 
							op2Type =18'b10_1111_0000_0000_0010;  // source 
							op1 = 32'd0; 
							op2 = 32'd0; 
							opSize =3'b101; // operand size is 128 bit 
							op1Type[9:7] = modR_M_Byte[5:3]; //destination register 
							op2Type[9:7] = modR_M_Byte[2:0]; //source register 
						end 
				end//if(opCode2[7:0] == 2'b11) 
			else 
				begin 
					if (escPrefix)		//if escape prefix  is set 
						begin 
							modR_M_Byte = opCode2; 
							op2Type[0] = 1'b0; 
							op1Type[9:7] = modR_M_Byte[5:3]; //destination register 
							op2Type[17] = 1'b0; // indirect addresing(memory addressing) 
							op1Type =18'b10_1111_0000_0000_0010;  //destination 
							op1 = 32'd0; 
							op2 = 32'd0; 
							opSize =3'b101; // operand size is 128 bit 
						end	//if (escPrefix)	 
					else 
						begin 
							op2Type[0] = 1'b0; 
							op2Type[17] = 1'b0; // indirect addresing(memory addressing) 
							op1Type =18'b10_1111_0000_0000_0000;  //destination 
							op1 = 32'd0; 
							op2 = 32'd0; 
							case(opCode1[3:0]) 
									4'hF:	opSize =3'b001; // operand size is 16 bit	//FISTTP 
									4'hB:	opSize =3'b010; // operand size is 32 bit 
									4'hD:	opSize =3'b011; // operand size is 64 bit 
 
							endcase 
						end 
				end		//else of if(opCode2[7:6] ==2'b11) 			 
 
			case(opCode2[7:6]) 
							 
				2'b00:  // if mod bit is 00 
					begin 
						if(!addressSize)  //16 bit addressing 
							begin 
								if(modR_M_Byte[2:0] == 3'b110)  // 16 bit displacement 
									begin 
										op2Type[13:12] = 2'b01; 
										op2[16:0] = instrSeq[31:16];  //displacemt alone							 
									end 
								else 
									begin 
										if ((modR_M_Byte[2:1] == 2'b00) ||(modR_M_Byte[2:0] == 3'b111)) // base = BX 
											begin 
												op2Type[8:5]	= 4'b0011; 
												op2Type[11:9] 	= 3'b011;  
											end 
										if (modR_M_Byte[2:1] == 2'b01)  //base = BP 
											//	if(!((modR_M_Byte[7:6] == 00) &&(modR_M_Byte[2:0] == 3'b110))) 
											begin 
												op2Type[8:5]	= 4'b0101; 
												op2Type[11:9]	= 3'b010; 
											end 
										if ((modR_M_Byte[0] == 0) && (modR_M_Byte[2:1] != 2'b11)) // index = SI 
											op2Type[4:2]	= 3'b110; 
										if ((modR_M_Byte[0] == 1) && (modR_M_Byte[2:1] != 2'b11)) // index = DI 
														op2Type[4:2]	= 3'b111; 
									end 
							end  //if(!adressSize) 
						else  //if 32 bit addressing 
							begin 
								case (modR_M_Byte[2:0])  
									3'b101:  // 32 bit displacement 
										begin 
											op2Type[13:12] = 2'b10; 
											op2 = instrSeq[55:24];  //displacemt alone							 
										end 
									3'b100:  // SIB Byte  present 
										begin 
											SIB_Byte = instrSeq[23:16];	// 
											op2Type[1:0] 	= SIB_Byte[7:6]; // scale 
											op2Type[4:2]	= SIB_Byte[5:3]; // index 
											op2Type[7:5]	= SIB_Byte[2:0]; // base 
											op2Type[8]	= 0; // base 
											if( op2Type[7:5] == 3'b100) 
												op2Type[11:9] = 3'b010; // segment = SS 
											else if( op2Type[7:5] == 3'b101)//only displacement  with no  base 
												begin 
													op2Type[11:9] = 3'b011; // segment = DS 
													op2Type[8:5] = 4'b1000;//no  base 
													op2Type[13:12] = 2'b10; // 32 bit displacement is present 
													op2 = instrSeq[55:24]; //displacement is there in op2 
												end 
											else 
												op2Type[11:9] = 3'b011; // segment = DS 
										end 
									default 
										begin 
											op2Type[7:5] = modR_M_Byte[2:0];   //base is in the R/M  field 
											op2Type[8]   = 0; 
											op2Type[11:9]= 3'b011; // segment = DS 
										end 
									endcase  //(modR_M_Byte[2:0])  
							end //else  of if(!adressSize) 
					end  //case 2'b00: 
			 
				2'b01:  //if mod bit is 01 
					begin 
						op2Type[13:12] = 2'b0; // 8 bit displacement is present 
						if(!addressSize)  //16 bit addressing 
							begin 
								op2[7:0] = instrSeq[23:15]; //displacement is there in op2 
								if ((modR_M_Byte[2:1] == 2'b00) ||(modR_M_Byte[2:0] == 3'b111)) // base = BX 
									begin 
										op2Type[8:5]	= 4'b0011; //base BX 
										op2Type[11:9] 	= 3'b011;   //data segment 
									end 
								if ( (modR_M_Byte[2:1] == 2'b01) ||(modR_M_Byte[2:0] == 3'b110)) //base = BP 
									begin 
										op2Type[8:5]	= 4'b0101;  //base BP 
										op2Type[11:9]	= 3'b010;   //stack segment 
												end 
											if ((modR_M_Byte[0] == 0) && (modR_M_Byte[2:1] != 2'b11)) // index = SI 
												op2Type[4:2]	= 3'b110; 
											if ((modR_M_Byte[0] == 1) && (modR_M_Byte[2:1] != 2'b11)) // index = DI 
												op2Type[4:2]	= 3'b111; 
										end  //if(!adressSize) 
									else  //if 32 bit addressing 
										begin 
									 
											case (modR_M_Byte[2:0])  
												3'b100:  // SIB Byte  present 
													begin 
														SIB_Byte = instrSeq[23:16]; 
														op2Type[1:0] 	= SIB_Byte[7:6]; // scale 
														op2Type[4:2]	= SIB_Byte[5:3]; // index 
														op2Type[7:5]	= SIB_Byte[2:0]; // base 
														op2Type[8]	= 0; // base 
														if( op2Type[7:5] == 3'b100) 
															op2Type[11:9] = 3'b010; // segment = SS 
											 
														else 
															op2Type[11:9] = 3'b011; // segment = DS 
														op2[7:0] = instrSeq[31:24]; //displacement is there in op2 
													end 
												default 
													begin 
														op2Type[7:5] = modR_M_Byte[2:0];   //base is in the R/M  field 
														op2Type[8]   = 0; 
														if(modR_M_Byte[2:0] == 3'b101) 
															op2Type[11:9] = 3'b010; // segment = SS 
														else 
															op2Type[11:9] = 3'b011; // segment = DS 
															op2[7:0] = instrSeq[23:16]; //displacement is there in op2 
													end 
										endcase  //(modR_M_Byte[2:0])  
										end //else  of if(!adressSize) 
					end  //case 2'b01: 
 
							2'b10:  // if mod bit is 10 
		 
								begin 
									if(!addressSize)  //16 bit addressing 
										begin 
											op2Type[13:12] = 2'b10; // 16 bit displacement is present 
											op2[15:0] = instrSeq[31:16]; //displacement is there in op2 
											if ((modR_M_Byte[2:1] == 2'b00) ||(modR_M_Byte[2:0] == 3'b111)) // base = BX 
												begin 
													op2Type[8:5]	= 4'b0011; //base BX 
													op2Type[11:9] 	= 3'b011;   //data segment 
												end 
											if ( (modR_M_Byte[2:1] == 2'b01) ||(modR_M_Byte[2:0] == 3'b110)) //base = BP 
												begin 
													op2Type[8:5]	= 4'b0101;  //base BP 
													op2Type[11:9]	= 3'b010;   //stack segment 
												end 
											if ((modR_M_Byte[0] == 0) && (modR_M_Byte[2:1] != 2'b11)) // index = SI 
												op2Type[4:2]	= 3'b110; 
											if ((modR_M_Byte[0] == 1) && (modR_M_Byte[2:1] != 2'b11)) // index = DI 
												op2Type[4:2]	= 3'b111; 
										end  //if(!adressSize) 
									else  //if 32 bit addressing 
										begin 
											op2Type[13:12] = 2'b10; // 32 bit displacement is present 
												case (modR_M_Byte[2:0])  
													3'b100:  // SIB Byte  present 
														begin 
															SIB_Byte = instrSeq[23:16]; 
															op2Type[1:0] 	= SIB_Byte[7:6]; // scale 
															op2Type[4:2]	= SIB_Byte[5:3]; // index 
															op2Type[7:5]	= SIB_Byte[2:0]; // base 
															op2Type[8]	= 0; // base 
															if( op2Type[7:5] == 3'b100) 
																op2Type[11:9] = 3'b010; // segment = SS 
															else 
																op2Type[11:9] = 3'b011; // segment = DS 
															op2 = instrSeq[55:24]; //displacement is there in op2 
			 
														end 
													default 
														begin 
															op2Type[7:5] = modR_M_Byte[2:0];   //base is in the R/M  field 
															op2Type[8]   = 0; 
															if(modR_M_Byte[2:0] == 3'b101) 
																op2Type[11:9] = 3'b010; // segment = SS 
															else 
																op2Type[11:9] = 3'b011; // segment = DS 
															op2 = instrSeq[47:16]; //displacement is there in op2 
													 
														end 
												endcase  //(modR_M_Byte[2:0])  
										end //else  of if(!adressSize) 
								end  //case 2'b10: 
						endcase		//	case(opCode[7:6]) 
 
			//	end		//else of opCode[7:6] == 2'b11    
		 
 
				if(directionFlag == 1'b1)// if direction flag is set 
					begin 
						tempOpType 	= op1Type; 
						op1Type 	= op2Type; 
						op2Type 	= tempOpType; 
						tempOp		= op1; 
						op1		= op2; 
						op2		= op1; 
					end 
 
				directionFlag = 1'b0;   
			 
		end // if (enable == 1) 
	end //always@(Enable)  
 
 
endmodule