<!--
	Assembler Encoding for the ShiftLeft Mnemonic
	Version: 1.0.0
	Date Created:  2007-05-10
	Last Modified: 2007-09-29

	Designed for Pentium and higher x86 Processors in 32bit mode protected mode
	Optimized for Size

	Notes:
	o Shifting by anything that is larger than 8bits will only use the lower 8bits.
		We may decide to clear to zero if any value is larger than 256, which would significantly slow this operation
		down, OR we can decide to live with this "limitation"
	o Shifting by oversized values (such as 32 or higher) DOES NOT work. The x86 processor stupidly does a & 31 on all
	  rotation values, making it impossible to have them work properly (ie, clear to zero).
	  We may add clear to zero testing, which would require branching !! but would fix this problem... it'd also
	  significantly slow this operation down

	Done list:
	o U/S8-256,Boolean to U/S8-32,Boolean

	To Do:
	o U/S8-256,Boolean to U/S48-256
-->
<encoding procfamily="x86" bitdepth="32" proc="Pentium">
	<!-- ############################################################################################################ -->
	<!-- ############################################################################################################ -->
	<!-- ############################################################################################################ -->
	<!-- ShiftLeft Mnemonic -->
	<mnemonic name="ShiftLeft" type="Assign" option="Size">
		<!-- ********************************************************************************************************** -->
		<!-- ShiftLefting 8bit values -->

		<!-- $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ -->
		<!-- From 8-256bit -->
		<codetypeset param0="U/S8" param1="U/S8-256">
			<codeset param0="M,R" param1="M,R" total="6" totalv="6" id="SHLUS8-256ToUS8_MR_MR"
				lostregs="al" endregs="al=cl" endpipe="U">
				<line code="mov al, cl"    time="U 1" timev=" V1" comment="Save CL" />
				<line code="mov cl, @1.U8" time=" V1" timev="U 1" comment="Get the value to shift by" />
				<line code="shl @0.U8, cl" time="&#45;&#45;4"     comment="Shift left" />
				<line code="mov cl, al"    time="U 1"             comment="Get CL back" />
			</codeset>
			<codeset param0="M" param1="I" total="3" endpipe="V">
				<line code="shl @0.U8, @1.U8" time="&#45;&#45;3" comment="Shift left (assume not pipable)" />
			</codeset>
			<codeset param0="R.U8=cl" param1="M,R" total="6" totalv="6" id="SHLUS8-256ToUS8_Rcl_MR"
				lostregs="al" endregs="al=@0.U8" endpipe="U">
				<line code="mov al, cl"    time="U 1" timev=" V1" comment="Move CL to AL" />
				<line code="mov cl, @1.U8" time=" V1" timev="U 1" comment="Get the value to shift by" />
				<line code="shl al, cl"    time="&#45;&#45;4"     comment="Shift left" />
				<line code="mov cl, al"    time="U 1"             comment="Store the result" />
			</codeset>
			<codeset param0="M,R" param1="R.U8=cl" total="4" id="SHLUS8-256ToUS8_MR_Rcl" endpipe="V">
				<line code="shl @0.U8, cl" time="&#45;&#45;4" comment="Shift left" />
			</codeset>

			<codeset param0="R" param1="I" total="1" endpipe="U">
				<line code="shl @0.U8, @1.U8" time="U!1" comment="Shift left" />
			</codeset>

			<codeset param0="M,R" param1="I=0" total="0" endpipe="-">
				<!-- Do Nothing -->
			</codeset>
		</codetypeset>


		<!-- $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ -->
		<!-- From Boolean -->
		<codetypeset param0="U/S8" param1="Boolean">
			<codeset param0="M,R" param1="M,R" sameas="SHLUS8-256ToUS8_MR_MR" />
			<codeset param0="R.U8=cl" param1="M,R" sameas="SHLUS8-256ToUS8_Rcl_MR" />
			<codeset param0="M,R" param1="R.U8=cl" sameas="SHLUS8-256ToUS8_MR_Rcl" />
		</codetypeset>



		<!-- ********************************************************************************************************** -->
		<!-- ShiftLefting 16bit values -->

		<!-- $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ -->
		<!-- From 8-256bit -->
		<codetypeset param0="U/S16" param1="U/S8-256">
			<codeset param0="M" param1="M,R" total="7" totalv="7" id="SHLUS8-256ToUS16_M_MR"
				lostregs="al" endregs="al=cl" endpipe="U">
				<line code="mov al, cl"     time="U 1"   timev=" V1" comment="Save CL" />
				<line code="mov cl, @1.U8"  time=" V1"   timev="U 1" comment="Get the value to shift by" />
				<line code="shl @0.U16, cl" time="&#45;&#45;4+1"     comment="Shift left" />
				<line code="mov cl, al"     time="U 1"               comment="Get CL back" />
			</codeset>
			<codeset param0="M" param1="R.U8=cl" total="5" id="SHLUS8-256ToUS16_M_Rcl" endpipe="V">
				<line code="shl @0.U16, cl" time="&#45;&#45;4+1" comment="Shift left" />
			</codeset>
			<codeset param0="M" param1="I" total="4" endpipe="V">
				<line code="shl @0.U16, @1.U8" time="&#45;&#45;3+1" comment="Shift left (assume not pipable)" />
			</codeset>

			<codeset param0="R" param1="M,R" total="6" totalv="6" id="SHLUS8-256ToUS16_R_MR"
				lostregs="al" endregs="al=cl" endpipe="U">
				<line code="mov al, cl"     time="U 1" timev=" V1" comment="Save CL" />
				<line code="mov cl, @1.U8"  time=" V1" timev="U 1" comment="Get the value to shift by" />
				<line code="shl @0.U32, cl" time="&#45;&#45;4"     comment="Shift left the full register value" />
				<line code="mov cl, al"     time="U 1"             comment="Get CL back" />
			</codeset>
			<codeset param0="R.U8=cl" param1="M,R" total="6" totalv="6" id="SHLUS8-256ToUS16_Rcl_MR"
				lostregs="eax" endregs="eax=@0.U32" endpipe="U">
				<line code="mov eax, ecx"  time="U 1" timev=" V1" comment="Move ECX to EAX" />
				<line code="mov cl, @1.U8" time=" V1" timev="U 1" comment="Get the value to shift by" />
				<line code="shl eax, cl"   time="&#45;&#45;4"     comment="Shift left the full register value" />
				<line code="mov ecx, eax"  time="U 1"             comment="Store it" />
			</codeset>
			<codeset param0="R" param1="R.U8=cl" total="4" id="SHLUS8-256ToUS16_R_Rcl" endpipe="V">
				<line code="shl @0.U32, cl" time="&#45;&#45;4" comment="Shift left the full register value" />
			</codeset>
			<codeset param0="R" param1="I" total="1" totalv="1" endpipe="U">
				<line code="shl @0.U32, @1.U8" time="U!1" comment="Shift left the full register value" />
			</codeset>

			<codeset param0="M,R" param1="I=0" total="0" endpipe="-">
				<!-- Do Nothing -->
			</codeset>
		</codetypeset>


		<!-- $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ -->
		<!-- From Boolean -->
		<codetypeset param0="U/S16" param1="Boolean">
			<codeset param0="M" param1="M,R" sameas="SHLUS8-256ToUS16_M_MR" />
			<codeset param0="M" param1="R.U8=cl" sameas="SHLUS8-256ToUS16_M_Rcl" />
			<codeset param0="R" param1="M,R" sameas="SHLUS8-256ToUS16_R_MR" />
			<codeset param0="R.U8=cl" param1="M,R" sameas="SHLUS8-256ToUS16_Rcl_MR" />
			<codeset param0="R" param1="R.U8=cl" sameas="SHLUS8-256ToUS16_R_Rcl" />
		</codetypeset>



		<!-- ********************************************************************************************************** -->
		<!-- ShiftLefting 24bit values -->

		<!-- $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ -->
		<!-- From 8-256bit -->
		<codetypeset param0="U/S24" param1="U/S8-256">
			<codeset param0="M" param1="M,R,I" total="9+?" totalv="8+?" id="SHLUS8-256ToUS24_M_MRI"
				lostregs="eax,edx" endregs="edx->@0" endpipe="U">
				<line code="mov al, @1.U8"          time="U 1"   timev=" V1" comment="Get the value to shift by" />
				<line code="lea edx, @0.U8"         time=" V1"   timev="U 1" comment="Get the pointer to our value" />
				<line code="call Mnemonic_SHL_US24" time="!V1+?"             comment="Shift the value" />
			</codeset>

			<codeset param0="R" param1="M,R" param1type="U24" total="3+?" totalv="2+?" id="SHLUS8-256ToU24_R_MR"
				lostregs="eax,dl" endregs="eax=@0.U24" endpipe="U">
				<line code="mov eax, @0.U32"         time="U 1" timev=" V1" comment="Get the value to shift" />
				<line code="mov dl, @1.U8"           time=" V1" timev="U 1" comment="Get the amount to shift" />
				<line code="call Mnemonic_SHL_U24_R" time="!V1+?"           comment="Shift it" />
				<line code="mov @0.U32, eax"         time="U 1"             comment="Store the result" />
			</codeset>
			<codeset param0="R" param1="M,R" param1type="S24" total="3+?" totalv="2+?" id="SHLUS8-256ToS24_R_MR"
				lostregs="eax,dl" endregs="eax=@0.S24" endpipe="U">
				<line code="mov eax, @0.U32"         time="U 1" timev=" V1" comment="Get the value to shift" />
				<line code="mov dl, @1.U8"           time=" V1" timev="U 1" comment="Get the amount to shift" />
				<line code="call Mnemonic_SHL_S24_R" time="!V1+?"           comment="Shift it" />
				<line code="mov @0.U32, eax"         time="U 1"             comment="Store the result" />
			</codeset>
			<codeset param0="R" param1="R.U8=cl" param1type="U24" total="5" id="SHLUS8-256ToU24_R_Rcl" endpipe="U">
				<line code="shl @0.U32, cl"       time="&#45;&#45;4" comment="Shift left the full register value" />
				<line code="and @0.U32, 0FFFFFFh" time="U 1"         comment="Clear the high byte" />
			</codeset>
			<codeset param0="R" param1="I" total="1" endpipe="U">
				<line code="shl @0.U32, @1.U8" time="U!1" comment="Shift left the full register value" />
			</codeset>

			<codeset param0="M,R" param1="I=0" total="0" endpipe="-">
				<!-- Do Nothing -->
			</codeset>
		</codetypeset>


		<!-- $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ -->
		<!-- From Boolean -->
		<codetypeset param0="U/S24" param1="Boolean">
			<codeset param0="M" param1="M,R" sameas="SHLUS8-256ToUS24_M_MRI" />
			<codeset param0="R" param1="M,R" param0type="U24" sameas="SHLUS8-256ToU24_R_MR" />
			<codeset param0="R" param1="M,R" param0type="S24" sameas="SHLUS8-256ToS24_R_MR" />
			<codeset param0="R" param1="R.U8=cl" param0type="U24" sameas="SHLUS8-256ToU24_R_Rcl" />
		</codetypeset>


		<!-- ********************************************************************************************************** -->
		<!-- ShiftLefting 32bit values -->

		<!-- $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ -->
		<!-- From 8-256bit -->
		<codetypeset param0="U/S32" param1="U/S8-256">
			<codeset param0="M,R" param1="M,R" total="6" totalv="6" id="SHLUS8-256ToUS32_MR_MR"
				lostregs="al" endregs="al=cl" endpipe="U">
				<line code="mov al, cl"     time="U 1" timev=" V1" comment="Save CL" />
				<line code="mov cl, @1.U8"  time=" V1" timev="U 1" comment="Get the value to shift by" />
				<line code="shl @0.U32, cl" time="&#45;&#45;4"     comment="Shift left" />
				<line code="mov cl, al"     time="U 1"             comment="Get CL back" />
			</codeset>
			<codeset param0="M" param1="I" total="3" endpipe="V">
				<line code="shl @0.U32, @1.U8" time="&#45;&#45;3" comment="Shift left (assume not pipable)" />
			</codeset>

			<codeset param0="R.U8=cl" param1="M,R" total="6" totalv="6" id="SHLUS8-256ToUS32_Rcl_MR"
				lostregs="eax" endregs="eax=@0.U32" endpipe="U">
				<line code="mov eax, ecx"  time="U 1" timev=" V1" comment="Move ECX to EAX" />
				<line code="mov cl, @1.U8" time=" V1" timev="U 1" comment="Get the value to shift by" />
				<line code="shl eax, cl"   time="&#45;&#45;4"     comment="Shift left the full register value" />
				<line code="mov ecx, eax"  time="U 1"             comment="Store it" />
			</codeset>
			<codeset param0="M,R" param1="R.U8=cl" total="4" id="SHLUS8-256ToUS32_MR_Rcl" endpipe="V">
				<line code="shl @0.U32, cl" time="&#45;&#45;4" comment="Shift left" />
			</codeset>
			<codeset param0="R" param1="I" total="1" endpipe="U">
				<line code="shl @0.U32, @1.U8" time="U!1" comment="Shift left" />
			</codeset>

			<codeset param0="M,R" param1="I=0" total="0" endpipe="-">
				<!-- Do Nothing -->
			</codeset>
		</codetypeset>


		<!-- $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ -->
		<!-- From Boolean -->
		<codetypeset param0="U/S32" param1="Boolean">
			<codeset param0="M,R" param1="M,R" sameas="SHLUS8-256ToUS32_MR_MR" />
			<codeset param0="R.U8=cl" param1="M,R" sameas="SHLUS8-256ToUS32_Rcl_MR" />
			<codeset param0="M,R" param1="R.U8=cl" sameas="SHLUS8-256ToUS32_MR_Rcl" />
		</codetypeset>



		<!-- ********************************************************************************************************** -->
		<!-- ShiftLefting Boolean -->

		<!-- $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ -->
		<!-- From 8-256bit -->
		<codetypeset param0="Boolean" param1="U/S8-256">
			<!-- 1/0 Version -->
			<codeset param0="M,R" param1="M" total="3-7" totalv="3-8" endpipe="?">
				<line code="cmp @1.U8, 0" time="U 2"      timev=" V2"      comment="Test if it's zero" />
				<line code="je > @l1"     time="!V1(+4?)" timev="!V1(+5?)" comment="If it's zero, do nothing" />
				<line code="mov @0.U8, 0" time="U 1"                       comment="Set it to zero" />
				<line code="@l1:" />
			</codeset>
			<codeset param0="M,R" param1="R" total="2-6" totalv="2-7" endpipe="?">
				<line code="test @1.U8, @1.U8" time="U 1"      timev=" V1"      comment="Test if it's zero" />
				<line code="jz > @l1"          time="!V1(+4?)" timev="!V1(+5?)" comment="If it's zero, do nothing" />
				<line code="mov @0.U8, 0"      time="U 1"                       comment="Set it to zero" />
				<line code="@l1:" />
			</codeset>

			<codeset param0="M" param1="R.U8=cl" total="7" endpipe="V">
				<line code="shl @0.U8, cl" time="&#45;&#45;4" comment="Shift left" />
				<line code="and @0.U8, 1"  time="U 3"         comment="Keep only the low bit" />
			</codeset>
			<codeset param0="R" param1="R.U8=cl" total="5" endpipe="V">
				<line code="shl @0.U8, cl" time="&#45;&#45;4" comment="Shift left" />
				<line code="and @0.U8, 1"  time="U 1"         comment="Keep only the low bit" />
			</codeset>
		</codetypeset>


		<!-- $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ -->
		<!-- From Boolean -->
		<codetypeset param0="Boolean" param1="Boolean">
			<!-- Bit shifting Boolean by Boolean is the same as ANDNOT -->
			<codeset param0="M" param1="M,R" total="5" totalv="4"
				lostregs="al" endpipe="U">
				<line code="mov al, @1.U8" time="U 1" timev=" V1" comment="Get the shift value" />
				<line code="xor al, 1"     time="U*1" timev="U 1" comment="Swap the bit" />
				<line code="and @0.U8, al" time="U*3"             comment="ANDNOT with the value" />
			</codeset>
			<codeset param0="M" param1="V" total="4" totalv="3"
				lostregs="@1.U8" endpipe="U">
				<line code="xor @1.U8, 1"     time="U 1" timev=" V1" comment="Swap the bit" />
				<line code="and @0.U8, @1.U8" time="U*3"             comment="ANDNOT with the value" />
			</codeset>
			<codeset param0="M,R" param1="I" total="1" totalv="0" endpipe="S">
				<line code="mov @0.U8, 0" time="U 1" timev=" V1" comment="Clear to zero" />
			</codeset>

			<codeset param0="R" param1="M,R" total="3" totalv="2"
				lostregs="al" endpipe="U">
				<line code="mov al, @1.U8" time="U 1" timev=" V1" comment="Get the shift value" />
				<line code="xor al, 1"     time="U*1" timev="U 1" comment="Swap the bit" />
				<line code="and @0.U8, al" time="U*1"             comment="ANDNOT with the value" />
			</codeset>

			<codeset param0="M,R" param1="I=0" total="0" endpipe="-">
				<!-- Do Nothing -->
			</codeset>
		</codetypeset>
	</mnemonic>
</encoding>
