<div dir="ltr">The X86 i16->i8 case is handled with these two patterns in X86InstrCompiler.td. One for 32-bit mode where we have to be careful to ensure we are starting from AX/BX/CX/DX. 64-bit uses a separate simpler pattern since SP/BP/SI/DI gain SPL/BPL/SIL/DIL in 64-bit mode.<div><br></div><div><div>def : Pat<(i8 (trunc GR16:$src)),</div><div> (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)),</div><div> sub_8bit)>,</div><div> Requires<[Not64BitMode]>;</div></div><div><br></div><div><div>def : Pat<(i8 (trunc GR16:$src)),</div><div> (EXTRACT_SUBREG GR16:$src, sub_8bit)>,</div><div> Requires<[In64BitMode]>;</div></div><div><br></div><div><br clear="all"><div><div dir="ltr" class="gmail_signature">~Craig</div></div><br></div></div><br><div class="gmail_quote"><div dir="ltr">On Mon, Aug 6, 2018 at 12:07 PM Michael Stellmann via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I'm working on defining the instructions and implementing the lowering <br>
code for a Z80 backend. For now, the backend supports only the native <br>
CPU-supported datatypes, which are 8 and 16 bits wide (i.e. no 32 bit <br>
long, float, ... yet).<br>
<br>
So far, a lot of the simple stuff like immediate loads and return values <br>
is very straightforward, but now I got stuck with ISD::TRUNCATE, as in:<br>
<br>
typedef unsigned char uint8_t;<br>
uint8_t Func(uint8_t val1) { return val1 + val1; }<br>
<br>
built with -O0 results in:<br>
<br>
target datalayout = "e-m:o-S8-p:16:8-p1:8:8-i16:8-i32:8-a:8-n8:16"<br>
target triple = "z80"<br>
; Function Attrs: noinline nounwind optnone<br>
define dso_local zeroext i8 @Func(i8 zeroext %val1) #0 {<br>
entry:<br>
%val1.addr = alloca i8, align 1<br>
store i8 %val1, i8* %val1.addr, align 1<br>
%0 = load i8, i8* %val1.addr, align 1<br>
%conv = zext i8 %0 to i16<br>
%1 = load i8, i8* %val1.addr, align 1<br>
%conv1 = zext i8 %1 to i16<br>
%add = add nsw i16 %conv, %conv1<br>
%conv2 = trunc i16 %add to i8<br>
ret i8 %conv2<br>
}<br>
<br>
I looked into the X86 backend, which has a Z80-like register design, <br>
i.e. being able to access the subregs AL (and AH) from AX directly, <br>
without any specific truncation operation necessary. But, to be honest, <br>
I do not really understand from the code where and how the i16 to i8 <br>
case is handled.<br>
<br>
So returning an 8 bit result would simply require loading the lower 8 <br>
bits ("AL" on X86) from the resulting value 16 bit (%add) into the 8 bit <br>
return register, as defined by the calling convention.<br>
(Or to be Z80 specific: The 16 bit add operation will be "ADD HL,DE", <br>
calling conv defined register "A" be the i8 return value, so the last <br>
two IR lines should emit something like "LD A,L / RET".)<br>
<br>
That said, what is the correct way to implement ISD::TRUNCATE this in <br>
the backend, using the CPU's capability that truncating i16 to i8 is <br>
simply accessing an i16' register's subreg?<br>
<br>
Should this be handled in "LowerOperation" or in "PerformDAGCombine"?<br>
Or could this be done with a target-independent combine?<br>
Would returning true in "isTruncateFree" suffice?<br>
Is any lowering code needed at all?<br>
<br>
The X86 backend seems to do both, "setTargetDAGCombine(ISD::TRUNCATE)", <br>
but then also registering a lot of MVTs via <br>
"setOperationAction(...,Custom)", depending on things like soft-float.<br>
I guess I'm<br>
<br>
And second:<br>
In my case, with only i16 and i8 data types, And are there other <br>
truncation operations to be supported? Is there any scenario where i8 to <br>
i1 is needed? My first guess was for conditional branching, but my tests <br>
showed that it works with flags, comparing "not equal" or "not zero", so <br>
I assume not.<br>
<br>
Michael<br>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
</blockquote></div>