126 lines
5.4 KiB
C++
126 lines
5.4 KiB
C++
//==-- W65816.h - Top-level interface for W65816 representation --*- C++ -*-==//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file contains the entry points for global functions defined in the
|
|
// LLVM W65816 backend.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_LIB_TARGET_W65816_W65816_H
|
|
#define LLVM_LIB_TARGET_W65816_W65816_H
|
|
|
|
#include "MCTargetDesc/W65816MCTargetDesc.h"
|
|
#include "llvm/Target/TargetMachine.h"
|
|
|
|
namespace W65816CC {
|
|
// 65816 branch condition codes. Encoded as i8 immediate operands in
|
|
// the BR_CC SDNode and tablegen patterns.
|
|
//
|
|
// 0..7 map to single Bxx instructions. 8..11 are pseudo codes that
|
|
// expand to a two-branch sequence — needed for SETGT/SETLE/SETUGT/
|
|
// SETULE when the operand we'd swap to LHS is a load (no
|
|
// pattern-match for load on LHS without spilling A). Only used in
|
|
// SELECT_CC16's custom inserter; never reaches a single Bxx.
|
|
enum CondCode {
|
|
COND_EQ = 0, // BEQ
|
|
COND_NE = 1, // BNE
|
|
COND_HS = 2, // BCS (unsigned >=)
|
|
COND_LO = 3, // BCC (unsigned <)
|
|
COND_MI = 4, // BMI (negative, signed <)
|
|
COND_PL = 5, // BPL (non-negative, signed >=)
|
|
COND_VS = 6, // BVS (overflow)
|
|
COND_VC = 7, // BVC (no overflow)
|
|
// Multi-branch pseudo codes (handled by SELECT_CC16 inserter):
|
|
COND_GT_MB = 8, // signed > : take if (PL && NE)
|
|
COND_LE_MB = 9, // signed <= : take if (MI || EQ)
|
|
COND_HI_MB = 10, // unsigned > : take if (HS && NE)
|
|
COND_LS_MB = 11, // unsigned <=: take if (LO || EQ)
|
|
COND_INVALID = -1
|
|
};
|
|
} // namespace W65816CC
|
|
|
|
namespace llvm {
|
|
|
|
class FunctionPass;
|
|
class W65816TargetMachine;
|
|
class PassRegistry;
|
|
|
|
FunctionPass *createW65816ISelDag(W65816TargetMachine &TM,
|
|
CodeGenOptLevel OptLevel);
|
|
|
|
// Post-RA cleanup: removes redundant STAfi+LDAfi same-slot pairs that
|
|
// the greedy allocator emits when materialising a COPY $a -> vreg as
|
|
// a spill/reload cycle, even though A still holds the value. See
|
|
// W65816StackSlotCleanup.cpp.
|
|
FunctionPass *createW65816StackSlotCleanup();
|
|
|
|
// Post-PEI cleanup: coalesces adjacent SEP/REP toggles emitted by
|
|
// STA8fi expansions when two i8 stores sit back-to-back. Each STA8fi
|
|
// emits SEP/STA/REP; consecutive expansions produce REP/SEP toggles
|
|
// that cancel. See W65816SepRepCleanup.cpp.
|
|
FunctionPass *createW65816SepRepCleanup();
|
|
|
|
// Pre-emit pass: expands long conditional branches into the
|
|
// `INVERTED_Bxx skip ; BRA target ; skip:` pattern when the byte
|
|
// distance to the target exceeds the +/-128 reach of an 8-bit-PCREL
|
|
// branch. The unconditional BRA is then auto-relaxed to BRL by
|
|
// the assembler when its target is also far. See W65816BranchExpand.cpp.
|
|
FunctionPass *createW65816BranchExpand();
|
|
|
|
// Pre-RA pass: when a tied-def Acc16 instruction has a source vreg
|
|
// whose value is also used after the consumer, fast regalloc fails
|
|
// to preserve it (the tied physreg gets overwritten). We insert
|
|
// explicit STAfi/LDAfi spill+reload around the consumer to fix this.
|
|
// See W65816TiedDefSpill.cpp.
|
|
FunctionPass *createW65816TiedDefSpill();
|
|
|
|
// Pre-RA pass: same trigger as TiedDefSpill, but bridges via X/Y
|
|
// (Idx16) instead of stack when the post-consumer range is free of
|
|
// X/Y clobbers. Saves 6 cycles + 2 bytes per bridge versus the stack
|
|
// route. See W65816ABridgeViaX.cpp.
|
|
FunctionPass *createW65816ABridgeViaX();
|
|
|
|
// Pre-RA pass: promote Acc16 vregs (= {A}) to Wide16 (= {A, IMG0..7}).
|
|
// Lets greedy regalloc spread i16 pressure across A and the DP-backed
|
|
// imaginaries. See W65816WidenAcc16.cpp.
|
|
FunctionPass *createW65816WidenAcc16();
|
|
|
|
// Post-RA peephole: replace STAfi/LDAfi spill pairs (5+5 cyc) with
|
|
// TAX/TXA bridges (2+2 cyc) when X is dead during the spill window.
|
|
// Targets fast-regalloc's habit of spilling A unnecessarily; the
|
|
// 3x speedup is the biggest single per-iteration win we can get
|
|
// without switching to a smarter allocator. See W65816SpillToX.cpp.
|
|
FunctionPass *createW65816SpillToX();
|
|
|
|
// Pre-emit peephole: rewrite `LDY #neg ; (LDA|STA) (sr,S),Y` to
|
|
// pre-add the offset to the pointer with Y=0. The 65816 spec for
|
|
// (sr,S),Y is a 24-bit add (DBR | (mem16(sr+S) + Y)) MOD $1000000,
|
|
// so signed-negative Y crosses bank boundaries. See W65816NegYIndY.cpp.
|
|
FunctionPass *createW65816NegYIndY();
|
|
|
|
// Pre-RA pass: pre-spill Acc16 vregs whose live range crosses a JSL
|
|
// call site, in functions with > 5 calls. Drops greedy regalloc
|
|
// pressure for high-call-count functions that would otherwise hit
|
|
// "ran out of registers". See W65816PreSpillCrossCall.cpp.
|
|
FunctionPass *createW65816PreSpillCrossCall();
|
|
|
|
void initializeW65816AsmPrinterPass(PassRegistry &);
|
|
void initializeW65816DAGToDAGISelLegacyPass(PassRegistry &);
|
|
void initializeW65816StackSlotCleanupPass(PassRegistry &);
|
|
void initializeW65816SepRepCleanupPass(PassRegistry &);
|
|
void initializeW65816BranchExpandPass(PassRegistry &);
|
|
void initializeW65816TiedDefSpillPass(PassRegistry &);
|
|
void initializeW65816ABridgeViaXPass(PassRegistry &);
|
|
void initializeW65816WidenAcc16Pass(PassRegistry &);
|
|
void initializeW65816SpillToXPass(PassRegistry &);
|
|
void initializeW65816NegYIndYPass(PassRegistry &);
|
|
void initializeW65816PreSpillCrossCallPass(PassRegistry &);
|
|
|
|
} // namespace llvm
|
|
|
|
#endif
|