[LLVMdev] TSFlags

Krzysztof Parzyszek kparzysz at codeaurora.org
Tue Jul 14 07:27:33 PDT 2015


All the "bits" variables (such as "s" and "p" below) are initialized 
from the values of the instruction operands.  The statement
   let InOperandList = !con(iops, (ins pred:$p, cc_out:$s));
concatenates the input operands provided so far with two extra ones: p 
and s.  The values corresponding to these arguments will be used to 
initialize "s" and "p".


For the initialization of the TSFlags, check the definition of 
InstTemplate in the same file:

class InstTemplate<AddrMode am, int sz, IndexMode im,
                    Format f, Domain d, string cstr, InstrItinClass itin>
   : Instruction {
   let Namespace = "ARM";
   [...]

   // The layout of TSFlags should be kept in sync with ARMBaseInfo.h.
   let TSFlags{4-0}   = AM.Value;
   let TSFlags{6-5}   = IndexModeBits;
   let TSFlags{12-7} = Form;
   let TSFlags{13}    = isUnaryDataProc;
   let TSFlags{14}    = canXformTo16Bit;
   let TSFlags{17-15} = D.Value;
   let TSFlags{18}    = thumbArithFlagSetting;

   [...]
}


You can get the final list of all records created by table-gen from the 
input .td files using this command (SRC = path to the LLVM sources):

llvm-tblgen -print-records -I SRC/lib/Target/ARM -I SRC/lib/Target -I 
SRC/include SRC/lib/Target/ARM/ARM.td -o output

Then, in the output file you can look at the actual definitions of all 
instructions after all macros/classes/etc have been processed.  You were 
looking at class sI, so let's find where sI is used:

We find that (for example) ADCri inherits from sI (the commented line 
shows all parent classes):

def ADCri {     // Instruction InstTemplate Encoding InstARM sI AsI1 
Requires Sched ri
   field bits<32> Inst = { p{3}, p{2}, p{1}, p{0}, 0, 0, 1, 0, 1, 0, 1, 
s{0}, Rn{3}, Rn{2}, Rn{1}, Rn{0}, Rd{3}, Rd{2}, Rd{1}, Rd{0}, imm{11}, 
imm{10}, imm{9}, imm{8}, imm{7}, imm{6}, imm{5}, imm{4}, imm{3}, imm{2}, 
imm{1}, imm{0} };
   field bits<32> Unpredictable = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
   field bits<32> SoftFail = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
   string Namespace = "ARM";
   dag OutOperandList = (outs GPR:$Rd);
   dag InOperandList = (ins GPR:$Rn, mod_imm:$imm, pred:$p, cc_out:$s);
   string AsmString = "adc${s}${p}       $Rd, $Rn, $imm";
   [...]
}

You can see that the InOperandList contains 4 operands: Rn, imm, p and 
s.  This is where the values used for instruction encoding will be taken 
from.


-Krzysztof


On 7/14/2015 8:49 AM, Sky Flyer wrote:
> Dear Krzysztof,
>
> That was really much of help. I did go through the ARM code trying to
> understand it.
> One question that I have is, how "s" and "p" get initialized? for
> example in this code that I copied from ARMInstrFormats.td
>
>
> // Same as I except it can optionally modify CPSR. Note it's modeled as
> an input
> // operand since by default it's a zero register. It will become an
> implicit def
> // once it's "flipped".
> class sI<dag oops, dag iops, AddrMode am, int sz,
>           IndexMode im, Format f, InstrItinClass itin,
>           string opc, string asm, string cstr,
>           list<dag> pattern>
>    : InstARM<am, sz, im, f, GenericDomain, cstr, itin> {
>    bits<4> p; // Predicate operand
>    bits<1> s; // condition-code set flag ('1' if the insn should set the
> flags)
>    let Inst{31-28} = p;
>    let Inst{20} = s;
>
>    let OutOperandList = oops;
>    let InOperandList = !con(iops, (ins pred:$p, cc_out:$s));
>    let AsmString = !strconcat(opc, "${s}${p}", asm);
>    let Pattern = pattern;
>    list<Predicate> Predicates = [IsARM];
> }
>
> The same for TSFlags; when I want to used them for condition handling,
> how do they get initialized?
>
>
> On Fri, Jul 10, 2015 at 5:59 PM, Krzysztof Parzyszek
> <kparzysz at codeaurora.org <mailto:kparzysz at codeaurora.org>> wrote:
>
>     On 7/10/2015 10:23 AM, Sky Flyer wrote:
>
>         Many thanks for your prompt reply.
>
>         I mean, imagine you have 3 bits for condition flags in your
>         instruction
>         (e.g.  overflow, zero, carry set, ...) for conditional
>         executions AND
>         there is no direct access to the Status Register, is it even
>         possible to
>         implement such scenario?
>
>
>     There doesn't have to be any explicit status register.  You can
>     either create separate instructions for each condition, or have the
>     condition as an extra operand.  Let's take "add" for example.  You
>     could have several versions of add:
>        add     add unconditionally
>        addc    add if carry
>        addz    add if zero
>        addo    add if overflow
>     and similarly for more complex conditions that your target could
>     support, such as "carry or zero".  This has the disadvantage that
>     the instruction set can get really large, but if the number of
>     conditional instructions is small or if the possible conditions vary
>     from one operation to another, this may be a viable solution.
>     The other option is to model the condition as an operand (I think
>     ARM does that).  So the add instruction could look like this:
>        R0 = add R1, R2, C
>     where
>        C = 0: no conditions
>        C = 1: zero
>        C = 2: carry
>        C = 4: overflow
>     etc.
>
>     This way the instruction set would remain small, but it may involve
>     special handling for it to work with the integrated assembler (if
>     the native instruction format is different than what you chose).
>
>     You could use the TSFlags to indicate for each instruction which
>     condition this instruction can modify.  Taking the add again, it
>     could modify all of the three: zero, carry and overflow, but a load
>     could only modify zero (for example, specifics would depend on your
>     target).
>
>
>
>     -Krzysztof
>
>
>     --
>     Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
>     hosted by The Linux Foundation
>     _______________________________________________
>     LLVM Developers mailing list
>     LLVMdev at cs.uiuc.edu <mailto:LLVMdev at cs.uiuc.edu> http://llvm.cs.uiuc.edu
>     http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>
>
>
>
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>


-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, 
hosted by The Linux Foundation



More information about the llvm-dev mailing list