Skip to content

Cherry-pick improvements for AVR codegen #149

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
3c4f514
[AVR] Fix incorrect decoding of conditional branch instructions
benshi001 Jan 7, 2023
6d0184a
[AVR][NFC] Remove redundant target feature PROGMEM
benshi001 Jan 13, 2023
83205f5
[AVR][NFC] Refactor 'AVRAsmPrinter::PrintAsmOperand'
benshi001 Jan 20, 2023
e8a78a6
[AVR] Optimize 16-bit comparison with a constant
benshi001 Jan 21, 2023
2f4a9d7
[AVR] Fix inaccurate offsets in PC relative branch instructions
benshi001 Feb 13, 2023
4d1912b
[AVR][MC] Add ELF flag 'EF_AVR_LINKRELAX_PREPARED' to OBJ files
benshi001 Feb 23, 2023
8dc25fa
[AVR] Fix incorrect flags of livein registers when spilling them
benshi001 Feb 24, 2023
0b320f8
[AVR] Fix incorrect expansion of the pseudo 'ELPMBRdZ' instruction
benshi001 Jan 8, 2023
6582eff
[AVR] Do not emit 'LPM Rd, Z' on devices without FeatureLPMX
benshi001 Jan 9, 2023
722c7b6
[AVR] Fix incorrect expansion of pseudo instructions LPMWRdZ/ELPMWRdZ
benshi001 Jan 9, 2023
d103fcc
[AVR] Reject invalid LDD instruction with explicit error
benshi001 Apr 9, 2023
ccd3588
[AVR][NFC] Fix errors in commit 6e57f68e41c92936b9ef3a4e6fb286e8805a9fbc
benshi001 Apr 10, 2023
614a431
[AVR] Disable post increment load from program memory space
benshi001 Apr 7, 2023
c5cadd1
[AVR] Fix an issue of writing 16-bit ports
benshi001 Jan 14, 2023
1c5fb0c
[AVR] Fix incorrect operands of pseudo instruction 'ROLBRd'
Patryk27 Jun 4, 2023
eeb4a65
[AVR][NFC][test] Suppement a test of the pseudo instruction RORBRd
benshi001 Jun 4, 2023
b0ad3bc
[AVR][NFC][test] Supplement more tests of 8-bit rotation
benshi001 Jun 5, 2023
4f9f7c0
[AVR][NFC] Improve CodeGen tests
benshi001 Jun 10, 2023
2f895d5
[AVR] Enable sub register liveness
benshi001 Jun 10, 2023
b9b277b
[AVR] Fix incorrect expansion of pseudo instruction ROLBRd
benshi001 Jun 7, 2023
1201a28
[AVR] Optimize 8-bit rotation when rotation bits >= 4
benshi001 Jun 11, 2023
894df9d
[AVR] Optimize 8-bit rotation when rotation bits == 3
benshi001 Jun 11, 2023
8b9c317
[AVR] Expand shifts of all types except int8 and int16
Patryk27 Jul 19, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions lld/test/ELF/avr-flags.s
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
; RUN: not ld.lld %t-v5 %t-xmega3 -o /dev/null 2>&1 | FileCheck --check-prefix ERR %s
; ERR: error: {{.*}}: cannot link object files with incompatible target ISA

; V5: Flags [ (0x5)
; V5: Flags [ (0x85)
; V5: EF_AVR_ARCH_AVR5 (0x5)
; XMEGA3: Flags [ (0x67)
; V5: EF_AVR_LINKRELAX_PREPARED (0x80)
; XMEGA3: Flags [ (0xE7)
; XMEGA3: EF_AVR_ARCH_XMEGA3 (0x67)
; XMEGA3: EF_AVR_LINKRELAX_PREPARED (0x80)
2 changes: 1 addition & 1 deletion lld/test/ELF/linkerscript/avr5.test
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
# RUN: llvm-readelf --headers %t/avr5b.out | FileCheck %s --check-prefix=HEAD

# HEAD: Atmel AVR 8-bit microcontroller
# HEAD: 0x5, EF_AVR_ARCH_AVR5
# HEAD: 0x85, EF_AVR_ARCH_AVR5, relaxable

# HEAD: Name Type Address Off Size
# HEAD-NEXT: NULL 00000000 000000 000000
Expand Down
73 changes: 34 additions & 39 deletions llvm/lib/Target/AVR/AVRAsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,56 +101,51 @@ bool AVRAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
const char *ExtraCode, raw_ostream &O) {
// Default asm printer can only deal with some extra codes,
// so try it first.
bool Error = AsmPrinter::PrintAsmOperand(MI, OpNum, ExtraCode, O);

if (Error && ExtraCode && ExtraCode[0]) {
if (ExtraCode[1] != 0)
return true; // Unknown modifier.
if (!AsmPrinter::PrintAsmOperand(MI, OpNum, ExtraCode, O))
return false;

if (ExtraCode[0] >= 'A' && ExtraCode[0] <= 'Z') {
const MachineOperand &RegOp = MI->getOperand(OpNum);
const MachineOperand &MO = MI->getOperand(OpNum);

assert(RegOp.isReg() && "Operand must be a register when you're"
"using 'A'..'Z' operand extracodes.");
Register Reg = RegOp.getReg();
if (ExtraCode && ExtraCode[0]) {
// Unknown extra code.
if (ExtraCode[1] != 0 || ExtraCode[0] < 'A' || ExtraCode[0] > 'Z')
return true;

unsigned ByteNumber = ExtraCode[0] - 'A';
// Operand must be a register when using 'A' ~ 'Z' extra code.
if (!MO.isReg())
return true;

unsigned OpFlags = MI->getOperand(OpNum - 1).getImm();
unsigned NumOpRegs = InlineAsm::getNumOperandRegisters(OpFlags);
(void)NumOpRegs;
Register Reg = MO.getReg();

const AVRSubtarget &STI = MF->getSubtarget<AVRSubtarget>();
const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
unsigned ByteNumber = ExtraCode[0] - 'A';
unsigned OpFlags = MI->getOperand(OpNum - 1).getImm();
unsigned NumOpRegs = InlineAsm::getNumOperandRegisters(OpFlags);

const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(Reg);
unsigned BytesPerReg = TRI.getRegSizeInBits(*RC) / 8;
assert(BytesPerReg <= 2 && "Only 8 and 16 bit regs are supported.");
const AVRSubtarget &STI = MF->getSubtarget<AVRSubtarget>();
const TargetRegisterInfo &TRI = *STI.getRegisterInfo();

unsigned RegIdx = ByteNumber / BytesPerReg;
if (RegIdx >= NumOpRegs)
return true;
Reg = MI->getOperand(OpNum + RegIdx).getReg();
const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(Reg);
unsigned BytesPerReg = TRI.getRegSizeInBits(*RC) / 8;
assert(BytesPerReg <= 2 && "Only 8 and 16 bit regs are supported.");

if (BytesPerReg == 2) {
Reg = TRI.getSubReg(Reg, ByteNumber % BytesPerReg ? AVR::sub_hi
: AVR::sub_lo);
}
unsigned RegIdx = ByteNumber / BytesPerReg;
if (RegIdx >= NumOpRegs)
return true;
Reg = MI->getOperand(OpNum + RegIdx).getReg();

O << AVRInstPrinter::getPrettyRegisterName(Reg, MRI);
return false;
if (BytesPerReg == 2) {
Reg = TRI.getSubReg(Reg,
ByteNumber % BytesPerReg ? AVR::sub_hi : AVR::sub_lo);
}
}

// Print global symbols.
const auto &MO = MI->getOperand(OpNum);
if (Error && MO.getType() == MachineOperand::MO_GlobalAddress) {
PrintSymbolOperand(MO, O);
O << AVRInstPrinter::getPrettyRegisterName(Reg, MRI);
return false;
}

if (Error)
printOperand(MI, OpNum, O);
if (MO.getType() == MachineOperand::MO_GlobalAddress)
PrintSymbolOperand(MO, O); // Print global symbols.
else
printOperand(MI, OpNum, O); // Fallback to ordinary cases.

return false;
}
Expand Down Expand Up @@ -259,9 +254,9 @@ bool AVRAsmPrinter::doFinalization(Module &M) {
auto *Section = cast<MCSectionELF>(TLOF.SectionForGlobal(&GO, TM));
if (Section->getName().startswith(".data"))
NeedsCopyData = true;
else if (Section->getName().startswith(".rodata") && SubTM->hasPROGMEM())
// AVRs that have a separate PROGMEM (that's most AVRs) store .rodata
// sections in RAM.
else if (Section->getName().startswith(".rodata") && SubTM->hasLPM())
// AVRs that have a separate program memory (that's most AVRs) store
// .rodata sections in RAM.
NeedsCopyData = true;
else if (Section->getName().startswith(".bss"))
NeedsClearBSS = true;
Expand Down
22 changes: 12 additions & 10 deletions llvm/lib/Target/AVR/AVRDevices.td
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,6 @@ def FeatureMOVW : SubtargetFeature<"movw", "m_hasMOVW", "true",
"The device supports the 16-bit MOVW "
"instruction">;

// The device has a separate flash namespace that must be accessed using special
// instructions like lpm.
def FeaturePROGMEM : SubtargetFeature<"progmem", "m_hasPROGMEM", "true",
"The device has a separate flash namespace">;

// The device supports the `LPM` instruction, with implied destination being r0.
def FeatureLPM : SubtargetFeature<"lpm", "m_hasLPM", "true",
"The device supports the `LPM` instruction">;
Expand Down Expand Up @@ -125,6 +120,12 @@ def FeatureTinyEncoding
"The device has Tiny core specific "
"instruction encodings">;

// When writing a 16-bit port or storing a 16-bit word, do the low byte first.
def FeatureLowByteFirst
: SubtargetFeature<"lowbytefirst", "m_hasLowByteFirst", "true",
"Do the low byte first when writing a 16-bit port or "
"storing a 16-bit word">;

// The device has CPU registers mapped in data address space
def FeatureMMR : SubtargetFeature<"memmappedregs", "m_hasMemMappedGPR", "true",
"The device has CPU registers "
Expand Down Expand Up @@ -161,7 +162,7 @@ def ELFArchXMEGA7 : ELFArch<"EF_AVR_ARCH_XMEGA7">;
// device should have.
def FamilyAVR0 : Family<"avr0", []>;

def FamilyAVR1 : Family<"avr1", [FamilyAVR0, FeatureLPM, FeaturePROGMEM, FeatureMMR]>;
def FamilyAVR1 : Family<"avr1", [FamilyAVR0, FeatureLPM, FeatureMMR]>;

def FamilyAVR2
: Family<"avr2",
Expand Down Expand Up @@ -197,17 +198,18 @@ def FamilyTiny
FeatureSmallStack]>;

def FamilyXMEGA3 : Family<"xmega3",
[FamilyAVR0, FeatureLPM, FeaturePROGMEM, FeatureIJMPCALL,
[FamilyAVR0, FeatureLPM, FeatureIJMPCALL,
FeatureADDSUBIW, FeatureSRAM, FeatureJMPCALL,
FeatureMultiplication, FeatureMOVW, FeatureLPMX,
FeatureBREAK]>;
FeatureBREAK, FeatureLowByteFirst]>;

def FamilyXMEGA : Family<"xmega",
[FamilyAVR0, FeatureLPM, FeaturePROGMEM, FeatureIJMPCALL,
[FamilyAVR0, FeatureLPM, FeatureIJMPCALL,
FeatureADDSUBIW, FeatureSRAM, FeatureJMPCALL,
FeatureMultiplication, FeatureMOVW, FeatureLPMX,
FeatureSPM, FeatureBREAK, FeatureEIJMPCALL,
FeatureSPMX, FeatureDES, FeatureELPM, FeatureELPMX]>;
FeatureSPMX, FeatureDES, FeatureELPM, FeatureELPMX,
FeatureLowByteFirst]>;

def FamilyXMEGAU : Family<"xmegau", [FamilyXMEGA, FeatureRMW]>;

Expand Down
Loading