//==-- 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