<!--
	Assembler Encoding for the SwitchEndian Mnemonic
	Version: 1.0.0
	Date Created:  2007-04-29
	Last Modified: 2007-09-29

	Designed for Pentium and higher x86 Processors in 32bit mode protected mode
	Optimized for Size

	Done list:
	o U/S8-256, Boolean

	To Do:
	o ???
-->
<encoding procfamily="x86" bitdepth="32" proc="Pentium">
	<!-- ############################################################################################################ -->
	<!-- ############################################################################################################ -->
	<!-- ############################################################################################################ -->
	<!-- SwitchEndian Mnemonic -->
	<mnemonic name="SwitchEndian" type="Unary" option="Size">
		<!-- ********************************************************************************************************** -->
		<!-- SwitchEndian on 8bit values -->
		<codetypeset param0="U/S8">
			<codeset param0="M,R" total="0" endpipe="-">
				<!-- Do Nothing -->
			</codeset>
		</codetypeset>



		<!-- ********************************************************************************************************** -->
		<!-- SwitchEndian on 16bit values -->
		<codetypeset param0="U/S16">
			<codeset param0="M" total="4" totalv="3"
				lostregs="ax" endregs="ah=@0.U8,al=@0.U8[1]" endpipe="U">
				<line code="mov ax, @0.U16"   time="U 1+1" timev=" V1+1" comment="Get the value" />
				<line code="mov @0.U8, ah"    time="U*1"   timev="U 1"   comment="Store the high byte into the low byte" />
				<line code="mov @0.U8[1], al" time="U*1"                 comment="Store the low byte into the high byte" />
			</codeset>

			<codeset param0="R" total="1" endpipe="U">
				<line code="ror @0.U16, 8" time="U!1" comment="Rotate the bits by 8, swapping the bits" />
			</codeset>
		</codetypeset>



		<!-- ********************************************************************************************************** -->
		<!-- SwitchEndian on 24bit values -->
		<codetypeset param0="U/S24">
			<codeset param0="M" total="4" totalv="3"
				lostregs="ax" endregs="ah=@0.U8,al=@0.U8[2]" endpipe="U">
				<line code="mov al, @0.U8"    time="U 1" timev=" V1" comment="Get the low byte" />
				<line code="mov ah, @0.U8[2]" time="U*1" timev="U 1" comment="Get the high byte" />
				<line code="mov @0.U8[2], al" time="U*1"             comment="Store the low byte into the high byte" />
				<line code="mov @0.U8, ah"    time="U*1"             comment="Store the high byte into the low byte" />
			</codeset>

			<codeset param0="R" param0type="U24" total="2+?" totalv="2+?"
				lostregs="eax,edx" endregs="eax=@0.U24" endpipe="U">
				<line code="mov eax, @0.U32"                  time="U 1"   timev=" V1" comment="Get the full register" />
				<line code="call Mnemonic_SwitchEndian_U24_R" time="!V1+?"             comment="Switch endian" />
				<line code="mov @0.U32, eax"                  time="U 1"               comment="Get the result" />
			</codeset>
			<codeset param0="R" param0type="S24" total="2+?" totalv="2+?"
				lostregs="eax,edx" endregs="eax=@0.S24" endpipe="U">
				<line code="mov eax, @0.U32"                  time="U 1"   timev=" V1" comment="Get the full register" />
				<line code="call Mnemonic_SwitchEndian_S24_R" time="!V1+?"             comment="Switch endian" />
				<line code="mov @0.U32, eax"                  time="U 1"               comment="Get the result" />
			</codeset>
		</codetypeset>



		<!-- ********************************************************************************************************** -->
		<!-- SwitchEndian on 32bit values -->
		<codetypeset param0="U/S32">
			<codeset param0="M" total="3" totalv="2"
				lostregs="eax" endregs="eax=@0.U32" endpipe="U">
				<line code="mov eax, @0.U32" time="U 1" timev=" V1" comment="Get the value" />
				<line code="bswap eax"       time="&#45;&#45;1"     comment="Switch endian" />
				<line code="mov @0.U32, eax" time="U 1"             comment="Store the value" />
			</codeset>

			<codeset param0="R" total="1" endpipe="V">
				<line code="bswap @0.U32" time="&#45;&#45;1" comment="Switch endian" />
			</codeset>
		</codetypeset>



		<!-- ********************************************************************************************************** -->
		<!-- SwitchEndian on 48bit values -->
		<codetypeset param0="U/S48">
			<codeset param0="M" total="1+?" totalv="1+?"
				lostregs="eax,edx" endregs="edx->@0.U8" endpipe="V">
				<line code="lea edx, @0.U8"                  time="U 1"   timev="V 1" comment="Get a pointer to the value" />
				<line code="call Mnemonic_SwitchEndian_US48" time="!V1+?"             comment="Switch endian" />
			</codeset>

			<codeset param0="R" param0type="U48" total="3+?" totalv="2+?"
				lostregs="eax,edx" endregs="eax=@0.U32,edx=@0.U16[2]" endpipe="V">
				<line code="mov eax, @0.U32"                  time="U 1"   timev=" V1" comment="Get the low 32 bits" />
				<line code="mov edx, @0.U32[1]"               time=" V1"   timev="U 1" comment="Get the full high 32 bits" />
				<line code="call Mnemonic_SwitchEndian_U48_R" time="!V1+?"             comment="Switch endian" />
				<line code="mov @0.U32, eax"                  time="U 1"               comment="Store the low 32 bits" />
				<line code="mov @0.U32[1], edx"               time=" V1"               comment="Store the full high 32 bits" />
			</codeset>
			<codeset param0="R" param0type="S48" total="3+?" totalv="2+?"
				lostregs="eax,edx" endregs="eax=@0.U32,edx=@0.S16[2]" endpipe="V">
				<line code="mov eax, @0.U32"                  time="U 1"   timev=" V1" comment="Get the low 32 bits" />
				<line code="mov edx, @0.U32[1]"               time=" V1"   timev="U 1" comment="Get the full high 32 bits" />
				<line code="call Mnemonic_SwitchEndian_S48_R" time="!V1+?"             comment="Switch endian" />
				<line code="mov @0.U32, eax"                  time="U 1"               comment="Store the low 32 bits" />
				<line code="mov @0.U32[1], edx"               time=" V1"               comment="Store the full high 32 bits" />
			</codeset>
		</codetypeset>



		<!-- ********************************************************************************************************** -->
		<!-- SwitchEndian on 64bit values -->
		<codetypeset param0="U/S64">
			<codeset param0="M" total="1+?" totalv="1+?"
				lostregs="eax,edx" endregs="edx->@0.U8" endpipe="V">
				<line code="lea edx, @0.U8"                  time="U 1"  timev=" V1" comment="Get a pointer to the value" />
				<line code="call Mnemonic_SwitchEndian_US64" time="!V1+?"            comment="Switch endian" />
				<!--
				Speed Version:
				<line code="mov eax, @0.U32"    time="U 1" timev=" V1" comment="Get the first 32 bits" />
				<line code="mov edx, @0.U32[1]" time=" V1" timev="U 1" comment="Get the high 32 bits" />
				<line code="bswap eax"          time="&#45;&#45;1"     comment="Switch endian in the first 32 bits" />
				<line code="bswap edx"          time="&#45;&#45;1"     comment="Switch endian in the high 32 bits" />
				<line code="mov @0.U32[1], eax" time="U 1"             comment="Store the swapped first 32 bits as the high 32 bits" />
				<line code="mov @0.U32, edx"    time=" V1"             comment="Store the swapped high 32 bits as the first 32 bits" />
				-->
			</codeset>

			<codeset param0="R" total="4" totalv="4"
				lostregs="eax" endregs="eax=@0.U32" endpipe="U">
				<line code="bswap @0.U32"          time="&#45;&#45;1" comment="Switch endian in the first 32 bits" />
				<line code="mov eax, @0.U32[1]"    time="U 1"         comment="Get the high 32 bits" />
				<line code="mov @0.U32[1], @0.U32" time=" V1"         comment="Store the swapped first 32 bits to the high 32 bits" />
				<line code="bswap eax"             time="&#45;&#45;1" comment="Switch endian in the high 32 bits" />
				<ilne code="mov @0.U32, eax"       time="U 1"         comment="Store the swapped high 32 bits to the low 32 bits" />
			</codeset>
		</codetypeset>



		<!-- ********************************************************************************************************** -->
		<!-- SwitchEndian on 128bit values -->
		<codetypeset param0="U/S128">
			<codeset param0="M" total="1+?" totalv="1+?"
				lostregs="eax,edx" endregs="edx->@0.U8" endpipe="V">
				<line code="lea edx, @0.U8"                   time="U 1"  timev=" V1" comment="Get a pointer to the value" />
				<line code="call Mnemonic_SwitchEndian_US128" time="!V1+?"            comment="Switch endian" />
			</codeset>

			<!-- Since this doesn't really exist, no point in making a Size version... -->
			<codeset param0="R" total="7" totalv="7"
				lostregs="eax" endregs="eax=@0.U32[1]" endpipe="V">
				<line code="bswap @0.U32"             time="&#45;&#45;1" comment="Switch endian in the first 32 bits" />
				<line code="mov eax, @0.U32[3]"       time="U 1"         comment="Get the high 32 bits" />
				<line code="mov @0.U32[3], @0.U32"    time=" V1"         comment="Store the swapped first 32 bits to the high 32 bits" />
				<line code="bswap eax"                time="&#45;&#45;1" comment="Switch endian in the high 32 bits" />
				<ilne code="mov @0.U32, eax"          time="U 1"         comment="Store the swapped high 32 bits to the low 32 bits" />

				<line code="mov eax, @0.U32[2]"       time=" V1"         comment="Get the third 32 bits" />
				<line code="bswap @0.U32[1]"          time="&#45;&#45;1" comment="Switch endian in the second 32 bits" />
				<line code="bswap eax"                time="&#45;&#45;1" comment="Switch endian in the third 32 bits" />
				<line code="mov @0.U32[2], @0.U32[1]" time="U 1"         comment="Store the swapped second 32 bits to the third 32 bits" />
				<ilne code="mov @0.U32[1], eax"       time=" V1"         comment="Store the swapped third 32 bits to the second 32 bits" />
			</codeset>
		</codetypeset>



		<!-- ********************************************************************************************************** -->
		<!-- SwitchEndian on 256bit values -->
		<codetypeset param0="U/S256">
			<codeset param0="M" total="1+?" totalv="1+?"
				lostregs="eax,edx" endregs="edx->@0.U8" endpipe="V">
				<line code="lea edx, @0.U8"                   time="U 1"  timev=" V1" comment="Get a pointer to the value" />
				<line code="call Mnemonic_SwitchEndian_US256" time="!V1+?"            comment="Switch endian" />
			</codeset>

			<!-- Since this doesn't really exist, no point in making a Size version... -->
			<codeset param0="R" total="14" totalv="14"
				lostregs="eax" endregs="eax=@0.U32[3]" endpipe="V">
				<line code="bswap @0.U32"             time="&#45;&#45;1" comment="Switch endian in the first 32 bits" />
				<line code="mov eax, @0.U32[7]"       time="U 1"         comment="Get the high 32 bits" />
				<line code="mov @0.U32[7], @0.U32"    time=" V1"         comment="Store the swapped first 32 bits to the high 32 bits" />
				<line code="bswap eax"                time="&#45;&#45;1" comment="Switch endian in the high 32 bits" />
				<ilne code="mov @0.U32, eax"          time="U 1"         comment="Store the swapped high 32 bits to the low 32 bits" />

				<line code="mov eax, @0.U32[6]"       time=" V1"         comment="Get the seventh 32 bits" />
				<line code="bswap @0.U32[1]"          time="&#45;&#45;1" comment="Switch endian in the second 32 bits" />
				<line code="bswap eax"                time="&#45;&#45;1" comment="Switch endian in the seventh 32 bits" />
				<line code="mov @0.U32[6], @0.U32[1]" time="U 1"         comment="Store the swapped second 32 bits to the seventh 32 bits" />
				<ilne code="mov @0.U32[1], eax"       time=" V1"         comment="Store the swapped sevength 32 bits to the second 32 bits" />

				<line code="bswap @0.U32[2]"          time="&#45;&#45;1" comment="Switch endian in the third 32 bits" />
				<line code="mov eax, @0.U32[5]"       time="U 1"         comment="Get the sixth 32 bits" />
				<line code="mov @0.U32[5], @0.U32[2]" time=" V1"         comment="Store the swapped third 32 bits to the sixth 32 bits" />
				<line code="bswap eax"                time="&#45;&#45;1" comment="Switch endian in the sixth 32 bits" />
				<ilne code="mov @0.U32[2], eax"       time="U 1"         comment="Store the swapped sixth 32 bits to the third 32 bits" />

				<line code="mov eax, @0.U32[4]"       time=" V1"         comment="Get the fifth 32 bits" />
				<line code="bswap @0.U32[3]"          time="&#45;&#45;1" comment="Switch endian in the fourth 32 bits" />
				<line code="bswap eax"                time="&#45;&#45;1" comment="Switch endian in the fifth 32 bits" />
				<line code="mov @0.U32[4], @0.U32[3]" time="U 1"         comment="Store the swapped fourth 32 bits to the fifth 32 bits" />
				<ilne code="mov @0.U32[3], eax"       time=" V1"         comment="Store the swapped fifth 32 bits to the fourth 32 bits" />
			</codeset>
		</codetypeset>



		<!-- ********************************************************************************************************** -->
		<!-- SwitchEndian on Boolean values -->
		<codetypeset param0="Boolean">
			<codeset param0="M,R" total="0" endpipe="-">
				<!-- Do Nothing -->
			</codeset>
		</codetypeset>
	</mnemonic>
</encoding>
