Instruction.xcc

Author: Benoit Dupont de Dinechin (Benoit.Dupont-de-Dinechin@st.com)

Copyright 2001 - 2007 STMicroelectronics

This program is free software; you can redistribute it and/or modify it under the terms of either (at your option): the GNU General Public License (GPL) version 2; the GNU Lesser General Public License (LGPL) version 2.1; any later version of these licences as published by the Free Software Foundation.

InstructionFlag— Enumerates the Instruction flags.
typedef enum {
  InstructionFlag_Control = 0x1,        // Instruction has Control effects.
  InstructionFlag_MemoryRead = 0x2,     // Instruction reads in Memory.
  InstructionFlag_MemoryWrite = 0x4,    // Instruction writes to Memory.
  InstructionFlag_SpillCode = 0x8,      // Instruction is spill code.
  InstructionFlag_Volatile = 0x10,      // Instruction is Volatile.
  InstructionFlag_Inductive = 0x20,     // Instruction defines a simple induction.
  InstructionFlag_SPUpdate = 0x40,      // Instruction updates stack pointer.
  InstructionFlag_Speculable = 0x100,   // Instruction is control speculable.
  InstructionFlag_Compensable = 0x200,  // Instruction is control compensable.
  InstructionFlag_InProlog = 0x400,     // Instruction is in software pipeline prolog.
  InstructionFlag_Kunrolled = 0x800,    // Instruction is software pipeline kunrolled.
} enum_InstructionFlag;
typedef uint16_t InstructionFlags;
InstructionAction— Read or write action of an Instruction on a StorageCell.
union InstructionAction_ {
  struct {
    int32_t CELL;
    int8_t STAGE;
    int8_t RAW;
    int8_t WAR;
    int8_t WAW;
  } __;
  uint64_t PACKED;
};
typedef union InstructionAction_ InstructionAction_, *InstructionAction;
typedef const union InstructionAction_ *restrict const_InstructionAction;
typedef union InstructionAction_ *restrict restrict_InstructionAction;
#define InstructionAction_CELL(this) ((this)->__.CELL)
#define InstructionAction__CELL(this) (&(this)->__.CELL)
#define InstructionAction_STAGE(this) ((this)->__.STAGE)
#define InstructionAction__STAGE(this) (&(this)->__.STAGE)
#define InstructionAction_RAW(this) ((this)->__.RAW)
#define InstructionAction__RAW(this) (&(this)->__.RAW)
#define InstructionAction_WAR(this) ((this)->__.WAR)
#define InstructionAction__WAR(this) (&(this)->__.WAR)
#define InstructionAction_WAW(this) ((this)->__.WAW)
#define InstructionAction__WAW(this) (&(this)->__.WAW)
#define InstructionAction_PACKED(this) ((this)->PACKED)
#define InstructionAction__PACKED(this) (&(this)->PACKED)
InstructionTask— Instruction fields needed to schedule Instruction(s).
struct InstructionTask_ {
  //@args       Instance instance
  Instance INSTANCE;            // This InstructionTask Instance.
  InstructionFlags FLAGS;               // This InstructionTask flags.
  //@access isControl   ((InstructionTask_FLAGS(this)&InstructionFlag_Control) != 0)
  //@access isMemoryRead        ((InstructionTask_FLAGS(this)&InstructionFlag_MemoryRead) != 0)
  //@access isMemoryWrite       ((InstructionTask_FLAGS(this)&InstructionFlag_MemoryWrite) != 0)
  //@access isVolatile  ((InstructionTask_FLAGS(this)&InstructionFlag_Volatile) != 0)
  //@access isInductive ((InstructionTask_FLAGS(this)&InstructionFlag_Inductive) != 0)
  //@access isSPUpdate  ((InstructionTask_FLAGS(this)&InstructionFlag_SPUpdate) != 0)
  //@access isSpeculable        ((InstructionTask_FLAGS(this)&InstructionFlag_Speculable) != 0)
  //@access isCompensable       ((InstructionTask_FLAGS(this)&InstructionFlag_Compensable) != 0)
  //@access isInProlog  ((InstructionTask_FLAGS(this)&InstructionFlag_InProlog) != 0)
  //@access isKunrolled ((InstructionTask_FLAGS(this)&InstructionFlag_Kunrolled) != 0)
  Indexed INDEXED;                      // This InstructionTask reference to Operation.
  //@access INDEX       Indexed_INDEX(InstructionTask_INDEXED(this))
  Scheduling SCHEDULING;                // The Scheduling class of this InstructionTask.
  Reservation RESERVATION;      // The Reservation of this InstructionTask.
  uint8_t PROCESSING;                   // This InstructionTask processing time.
  int8_t ITERATION;                     // The iteration during kernel unrolling.
  int32_t ORDERING;                     // For use by Instruction reordering.
  int16_t STARTDATE;                    // This InstructionTask start date.
  int16_t RELEASE;                      // This InstructionTask release date.
  int16_t CRITICAL;                     // Critical path length for Pipeline scheduling.
  int16_t PREDCOUNT;                    // Count of predecessors PipelineEffect(s).
  int16_t WRITECOUNT;                   // Cound of write InstructionAction(s).
  int16_t READCOUNT;                    // Cound of read InstructionAction(s).
  struct PipelineEffect_ *EFFECTS;      // This InstructionTask effects (writes then reads).
};
InstructionTask_compare— Compare function for sorting IssueItems.
int
InstructionTask_compare(const void *this_pointer, const void *that_pointer);
InstructionRelocatable— Record for an Instruction relocatable Operand.
struct InstructionRelocatable_ {
  //@args       const_OperandsBuffer buffer, Relocation relocation, Operands operands
  Constant CONSTANT;                    // The relocatable Constant if any.
  Relocation RELOCATION;                // The Relocation to apply before encoding.
  Operands OPERANDS;            // The Operands where the relocatable Operand is.
  uint8_t RANK;                         // The relocatable Operand rank in Operands.
};
Instruction— Representation of a native instruction.

Instruction opcode and operands are maintained in encoded form in the OPCODES.

When the Instruction needs to be constructed early, Operand encoding can be deferred by passing a NULL buffer argument. In such case, Instruction encoding can be completed later with Instruction_recode(). FIXME!

struct Instruction_ {
  //@args       Instance instance, const_OperandsBuffer buffer, Relocation relocation
  InstructionTask_ TASK[1];                     // The InstructionTask of this Instruction.
  //@access INDEX       InstructionTask_INDEX(Instruction_TASK(this))
  //@access INSTANCE    InstructionTask_INSTANCE(Instruction_TASK(this))
  //@access INDEXED     InstructionTask_INDEXED(Instruction_TASK(this))
  //@mutate INDEXED     InstructionTask__INDEXED(Instruction_TASK(this))
  //@access FLAGS       InstructionTask_FLAGS(Instruction_TASK(this))
  //@mutate FLAGS       InstructionTask__FLAGS(Instruction_TASK(this))
  //@access isControl   InstructionTask_isControl(Instruction_TASK(this))
  //@access isVolatile  InstructionTask_isVolatile(Instruction_TASK(this))
  //@access isMemoryRead        InstructionTask_isMemoryRead(Instruction_TASK(this))
  //@access isMemoryWrite       InstructionTask_isMemoryWrite(Instruction_TASK(this))
  //@access isSPUpdate  InstructionTask_isSPUpdate(Instruction_TASK(this))
  //@access RESERVATION InstructionTask_RESERVATION(Instruction_TASK(this))
  //@access PROCESSING  InstructionTask_PROCESSING(Instruction_TASK(this))
  //@access ITERATION   InstructionTask_ITERATION(Instruction_TASK(this))
  //@mutate ITERATION   InstructionTask__ITERATION(Instruction_TASK(this))
  //@access STARTDATE   InstructionTask_STARTDATE(Instruction_TASK(this))
  //@mutate STARTDATE   InstructionTask__STARTDATE(Instruction_TASK(this))
  //@access RELEASE     InstructionTask_RELEASE(Instruction_TASK(this))
  //@mutate RELEASE     InstructionTask__RELEASE(Instruction_TASK(this))
  //@access CRITICAL    InstructionTask_CRITICAL(Instruction_TASK(this))
  //@mutate CRITICAL    InstructionTask__CRITICAL(Instruction_TASK(this))
  //@access PREDCOUNT   InstructionTask_PREDCOUNT(Instruction_TASK(this))
  //@mutate PREDCOUNT   InstructionTask__PREDCOUNT(Instruction_TASK(this))
  //@access WRITECOUNT  InstructionTask_WRITECOUNT(Instruction_TASK(this))
  //@mutate WRITECOUNT  InstructionTask__WRITECOUNT(Instruction_TASK(this))
  //@access READCOUNT   InstructionTask_READCOUNT(Instruction_TASK(this))
  //@mutate READCOUNT   InstructionTask__READCOUNT(Instruction_TASK(this))
  //@access EFFECTS     InstructionTask_EFFECTS(Instruction_TASK(this))
  //@mutate EFFECTS     InstructionTask__EFFECTS(Instruction_TASK(this))
  InstructionRelocatable_ RELOCATABLE[1];       // The relocatable Constant if any.
  //@access hasRelocatable      (Instruction_relocatableConstant(this) != NULL)
  InstanceOpcodes_ OPCODES[1];                  // The opcodes of this Instruction.
  PlatformUInt ADDRESS;                         // Native code address.
  InstructionAction_ *ACTIONS;                  // This InstructionTask actions (writes then reads).
  InstructionAction_ ARRAY[InstructionTask_ACTIONS_COUNT_MAX];
};
Instruction_instance— This Instruction Instance.
static inline Instance
Instruction_instance(const_Instruction this)
{
  return Instruction_INSTANCE(this);
}
Instruction_startDate— This Instruction start date.
static inline int
Instruction_startDate(const_Instruction this)
{
  return Instruction_STARTDATE(this);
}
Instruction_setStartDate— Set this Instruction start date.
static inline void
Instruction_setStartDate(Instruction this, int startDate)
{
  *Instruction__STARTDATE(this) = startDate;
}
Instruction_flags— This Instruction flags.
static inline InstructionFlags
Instruction_flags(const_Instruction this)
{
  return Instruction_FLAGS(this);
}
Instruction_setFlags— Set Instruction flags.
static inline void
Instruction_setFlags(Instruction this, InstructionFlags flags)
{
  *Instruction__FLAGS(this) |= flags;
}
Instruction_clearFlags— Clear Instruction flags.
static inline void
Instruction_clearFlags(Instruction this, InstructionFlags flags)
{
  *Instruction__FLAGS(this) &= ~flags;
}
Instruction_indexed— This Instruction Indexed.
static inline Indexed
Instruction_indexed(const_Instruction this)
{
  return Instruction_INDEXED(this);
}
Instruction_setIndexed— Set this Instruction Indexed.
static inline void
Instruction_setIndexed(Instruction this, Indexed indexed)
{
  *Instruction__INDEXED(this) = indexed;
}
Instruction_actions— This Instruction InstructionAction(s).
static inline const InstructionAction_ *
Instruction_actions(const_Instruction this)
{
  return Instruction_ACTIONS(this);
}
Instruction_relocatable— This Instruction relocatable Constant.
static inline const_InstructionRelocatable
Instruction_relocatable(const_Instruction this)
{
  return Instruction_RELOCATABLE(this);
}
Instruction_relocatableConstant— This Instruction relocatable Constant.
static inline Constant
Instruction_relocatableConstant(const_Instruction this)
{
  return InstructionRelocatable_CONSTANT(Instruction_RELOCATABLE(this));
}
Instruction_relocatableRelocation— This Instruction relocatable Relocation.
static inline Relocation
Instruction_relocatableRelocation(const_Instruction this)
{
  return InstructionRelocatable_RELOCATION(Instruction_RELOCATABLE(this));
}
Instruction_opcodes— This Instruction opcodes.
static inline const_InstanceOpcodes
Instruction_opcodes(const_Instruction this)
{
  return Instruction_OPCODES(this);
}
Instruction_bundling— This Instruction Bundling class.
static inline Bundling
Instruction_bundling(const_Instruction this)
{
  Instance instance = Instruction_INSTANCE(this);
  Scheduling scheduling = Instance_scheduling(instance);
  return Scheduling_bundling(scheduling);
}
Instruction_makeActions— Make this Instruction ACTIONS array.

For control Instruction(s), the WAR latency is modified to ensure it is non-zero. This trick is motivated by the following sample code, where register $b1 is WAR:

BR $b1, target  # unscheduled
CMP $b1 = ...   # unscheduled

Without this trick, instruction scheduling could produce code like:

BR $b1, target  # cycle 0
CMP $b1 = ...   # cycle 0

However, the compiler needs the Instruction(s) in semantic order and in particular the control Instruction appear last in bundles. The code would be normalized to:

CMP $b1 = ...   # cycle 0
BR $b1, target  # cycle 0

This is incorrect reordering. Forcing a non-zero WAR latency will ensure:

BR $b1, target  # cycle 0
CMP $b1 = ...   # cycle 1
const InstructionAction_ *
Instruction_makeActions(Instruction this, const_OperandsBuffer buffer);

Instruction relocation fixup type.

typedef void (*InstructionRelocationFixup)(Instruction instruction,
                                           PlatformUInt nativePC,
                                           Relocation relocation,
                                           void* userData,
                                           void* stream);
Instruction_recode— Recode this Instruction from OperandsBuffer and Relocation.
void
Instruction_recode(Instruction this, const_OperandsBuffer buffer, Relocation relocation);
Instruction_decode— Decode an Instruction from Encoding and opcodes.
Instruction
Instruction_decode(Instruction this, Encoding encoding, const_InstanceOpcodes opcodes);
Instruction_pretty— Pretty-print this Instruction.
bool
Instruction_pretty(const_Instruction this, FILE *file, void *stream);

InstructionGroup -- Group of Instruction(s) that issue in parallel.

struct InstructionGroup_ {
  //@args
#if Bundle_ISSUE_MAX
  Bundle BUNDLE;                // Bundle for this InstructionGroup.
  Template TEMPLATE;    // Template for this InstructionGroup.
  uint8_t COUNT;                // Count of Instruction(s) in this InstructionGroup.
  Instruction INSTRUCTIONS[Bundle_ISSUE_MAX];
  BundlingBuffer_ BUFFER_;
  //@access BUFFER      InstructionGroup__BUFFER_(this)
  //@access BUNDLINGS   BundlingBuffer_BUNDLINGS(InstructionGroup_BUFFER(this))
  //@access PERMUTE     BundlingBuffer_PERMUTE(InstructionGroup_BUFFER(this))
#else//!Bundle_ISSUE_MAX
  Instruction INSTRUCTION;
#endif//Bundle_ISSUE_MAX
};
InstructionGroup_pretty— Pretty-print this InstructionGroup.
bool
InstructionGroup_pretty(const_InstructionGroup this, FILE *file,
                        void *stream, int offset);
InstructionStack— Stack of Instruction(s).
struct InstructionStack_ {
  //@args       Memory memory, int maxCount
  PtrSeq_ __;           // Underlying PtrSeq.
};
InstructionStack_FOREACH_Instruction— Iterate over this InstructionStack Instruction(s).
#define InstructionStack_FOREACH_Instruction(this, instruction) { \
  const_PtrSeq InstructionStack____ = InstructionStack__const(this); \
  PtrSeq_FOREACH(InstructionStack____, Instruction, instruction) {
#define InstructionStack_ENDEACH_Instruction \
  } PtrSeq_ENDEACH \
}
InstructionStack_FORBACK_Instruction— Iterate over this InstructionStack Instruction(s).
#define InstructionStack_FORBACK_Instruction(this, instruction) { \
  const_PtrSeq InstructionStack____ = InstructionStack__const(this); \
  PtrSeq_FORBACK(InstructionStack____, Instruction, instruction) {
#define InstructionStack_ENDBACK_Instruction \
  } PtrSeq_ENDBACK \
}