summaryrefslogtreecommitdiff
path: root/lib/Target/AVR
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/AVR')
-rw-r--r--lib/Target/AVR/AVRAsmPrinter.cpp5
-rw-r--r--lib/Target/AVR/AVRDevices.td23
-rw-r--r--lib/Target/AVR/AVRInstrInfo.cpp72
-rw-r--r--lib/Target/AVR/AVRInstrInfo.h4
-rw-r--r--lib/Target/AVR/AVRInstrInfo.td32
-rw-r--r--lib/Target/AVR/AVRMCInstLower.cpp16
-rw-r--r--lib/Target/AVR/AVRRegisterInfo.cpp11
-rw-r--r--lib/Target/AVR/AVRRegisterInfo.td7
-rw-r--r--lib/Target/AVR/AVRTargetMachine.cpp6
-rw-r--r--lib/Target/AVR/AsmParser/AVRAsmParser.cpp1
-rw-r--r--lib/Target/AVR/InstPrinter/AVRInstPrinter.cpp2
-rw-r--r--lib/Target/AVR/MCTargetDesc/AVRELFStreamer.cpp2
12 files changed, 134 insertions, 47 deletions
diff --git a/lib/Target/AVR/AVRAsmPrinter.cpp b/lib/Target/AVR/AVRAsmPrinter.cpp
index f0c7b11895b4a..c058c9e1f5348 100644
--- a/lib/Target/AVR/AVRAsmPrinter.cpp
+++ b/lib/Target/AVR/AVRAsmPrinter.cpp
@@ -149,7 +149,10 @@ bool AVRAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
(void)MO;
assert(MO.isReg() && "Unexpected inline asm memory operand");
- // TODO: We can look up the alternative name for the register if it's given.
+ // TODO: We should be able to look up the alternative name for
+ // the register if it's given.
+ // TableGen doesn't expose a way of getting retrieving names
+ // for registers.
if (MI->getOperand(OpNum).getReg() == AVR::R31R30) {
O << "Z";
} else {
diff --git a/lib/Target/AVR/AVRDevices.td b/lib/Target/AVR/AVRDevices.td
index 9224af613d148..62def45744372 100644
--- a/lib/Target/AVR/AVRDevices.td
+++ b/lib/Target/AVR/AVRDevices.td
@@ -6,7 +6,6 @@
// :TODO: We define all devices with SRAM to have all variants of LD/ST/LDD/STD.
// In reality, avr1 (no SRAM) has one variant each of `LD` and `ST`.
// avr2 (with SRAM) adds the rest of the variants.
-// :TODO: s/AVRTiny/Tiny
// A feature set aggregates features, grouping them. We don't want to create a
@@ -136,7 +135,7 @@ def ELFArchAVR4 : ELFArch<"EF_AVR_ARCH_AVR4">;
def ELFArchAVR5 : ELFArch<"EF_AVR_ARCH_AVR5">;
def ELFArchAVR51 : ELFArch<"EF_AVR_ARCH_AVR51">;
def ELFArchAVR6 : ELFArch<"EF_AVR_ARCH_AVR6">;
-def ELFArchAVRTiny : ELFArch<"EF_AVR_ARCH_AVRTINY">;
+def ELFArchTiny : ELFArch<"EF_AVR_ARCH_AVRTINY">;
def ELFArchXMEGA1 : ELFArch<"EF_AVR_ARCH_XMEGA1">;
def ELFArchXMEGA2 : ELFArch<"EF_AVR_ARCH_XMEGA2">;
def ELFArchXMEGA3 : ELFArch<"EF_AVR_ARCH_XMEGA3">;
@@ -189,7 +188,7 @@ def FamilyAVR51 : Family<"avr51",
def FamilyAVR6 : Family<"avr6",
[FamilyAVR51]>;
-def FamilyAVRTiny : Family<"avrtiny",
+def FamilyTiny : Family<"avrtiny",
[FamilyAVR0, FeatureBREAK, FeatureSRAM,
FeatureTinyEncoding]>;
@@ -240,7 +239,7 @@ def : Device<"avrxmega4", FamilyXMEGA, ELFArchXMEGA4>;
def : Device<"avrxmega5", FamilyXMEGA, ELFArchXMEGA5>;
def : Device<"avrxmega6", FamilyXMEGA, ELFArchXMEGA6>;
def : Device<"avrxmega7", FamilyXMEGA, ELFArchXMEGA7>;
-def : Device<"avrtiny", FamilyAVRTiny, ELFArchAVRTiny>;
+def : Device<"avrtiny", FamilyTiny, ELFArchTiny>;
// Specific MCUs
def : Device<"at90s1200", FamilyAVR0, ELFArchAVR1>;
@@ -480,12 +479,12 @@ def : Device<"atxmega384d3", FamilyXMEGA, ELFArchXMEGA6>;
def : Device<"atxmega128a1", FamilyXMEGA, ELFArchXMEGA7>;
def : Device<"atxmega128a1u", FamilyXMEGAU, ELFArchXMEGA7>;
def : Device<"atxmega128a4u", FamilyXMEGAU, ELFArchXMEGA7>;
-def : Device<"attiny4", FamilyAVRTiny, ELFArchAVRTiny>;
-def : Device<"attiny5", FamilyAVRTiny, ELFArchAVRTiny>;
-def : Device<"attiny9", FamilyAVRTiny, ELFArchAVRTiny>;
-def : Device<"attiny10", FamilyAVRTiny, ELFArchAVRTiny>;
-def : Device<"attiny20", FamilyAVRTiny, ELFArchAVRTiny>;
-def : Device<"attiny40", FamilyAVRTiny, ELFArchAVRTiny>;
-def : Device<"attiny102", FamilyAVRTiny, ELFArchAVRTiny>;
-def : Device<"attiny104", FamilyAVRTiny, ELFArchAVRTiny>;
+def : Device<"attiny4", FamilyTiny, ELFArchTiny>;
+def : Device<"attiny5", FamilyTiny, ELFArchTiny>;
+def : Device<"attiny9", FamilyTiny, ELFArchTiny>;
+def : Device<"attiny10", FamilyTiny, ELFArchTiny>;
+def : Device<"attiny20", FamilyTiny, ELFArchTiny>;
+def : Device<"attiny40", FamilyTiny, ELFArchTiny>;
+def : Device<"attiny102", FamilyTiny, ELFArchTiny>;
+def : Device<"attiny104", FamilyTiny, ELFArchTiny>;
diff --git a/lib/Target/AVR/AVRInstrInfo.cpp b/lib/Target/AVR/AVRInstrInfo.cpp
index afba66b2e69bb..744aa723c416c 100644
--- a/lib/Target/AVR/AVRInstrInfo.cpp
+++ b/lib/Target/AVR/AVRInstrInfo.cpp
@@ -402,7 +402,7 @@ unsigned AVRInstrInfo::insertBranch(MachineBasicBlock &MBB,
ArrayRef<MachineOperand> Cond,
const DebugLoc &DL,
int *BytesAdded) const {
- assert(!BytesAdded && "code size not handled");
+ if (BytesAdded) *BytesAdded = 0;
// Shouldn't be a fall through.
assert(TBB && "insertBranch must not be told to insert a fallthrough");
@@ -411,19 +411,24 @@ unsigned AVRInstrInfo::insertBranch(MachineBasicBlock &MBB,
if (Cond.empty()) {
assert(!FBB && "Unconditional branch with multiple successors!");
- BuildMI(&MBB, DL, get(AVR::RJMPk)).addMBB(TBB);
+ auto &MI = *BuildMI(&MBB, DL, get(AVR::RJMPk)).addMBB(TBB);
+ if (BytesAdded)
+ *BytesAdded += getInstSizeInBytes(MI);
return 1;
}
// Conditional branch.
unsigned Count = 0;
AVRCC::CondCodes CC = (AVRCC::CondCodes)Cond[0].getImm();
- BuildMI(&MBB, DL, getBrCond(CC)).addMBB(TBB);
+ auto &CondMI = *BuildMI(&MBB, DL, getBrCond(CC)).addMBB(TBB);
+
+ if (BytesAdded) *BytesAdded += getInstSizeInBytes(CondMI);
++Count;
if (FBB) {
// Two-way Conditional branch. Insert the second branch.
- BuildMI(&MBB, DL, get(AVR::RJMPk)).addMBB(FBB);
+ auto &MI = *BuildMI(&MBB, DL, get(AVR::RJMPk)).addMBB(FBB);
+ if (BytesAdded) *BytesAdded += getInstSizeInBytes(MI);
++Count;
}
@@ -432,7 +437,7 @@ unsigned AVRInstrInfo::insertBranch(MachineBasicBlock &MBB,
unsigned AVRInstrInfo::removeBranch(MachineBasicBlock &MBB,
int *BytesRemoved) const {
- assert(!BytesRemoved && "code size not handled");
+ if (BytesRemoved) *BytesRemoved = 0;
MachineBasicBlock::iterator I = MBB.end();
unsigned Count = 0;
@@ -450,6 +455,7 @@ unsigned AVRInstrInfo::removeBranch(MachineBasicBlock &MBB,
}
// Remove the branch.
+ if (BytesRemoved) *BytesRemoved += getInstSizeInBytes(*I);
I->eraseFromParent();
I = MBB.end();
++Count;
@@ -494,5 +500,61 @@ unsigned AVRInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
}
}
+MachineBasicBlock *
+AVRInstrInfo::getBranchDestBlock(const MachineInstr &MI) const {
+ switch (MI.getOpcode()) {
+ default:
+ llvm_unreachable("unexpected opcode!");
+ case AVR::JMPk:
+ case AVR::CALLk:
+ case AVR::RCALLk:
+ case AVR::RJMPk:
+ case AVR::BREQk:
+ case AVR::BRNEk:
+ case AVR::BRSHk:
+ case AVR::BRLOk:
+ case AVR::BRMIk:
+ case AVR::BRPLk:
+ case AVR::BRGEk:
+ case AVR::BRLTk:
+ return MI.getOperand(0).getMBB();
+ case AVR::BRBSsk:
+ case AVR::BRBCsk:
+ return MI.getOperand(1).getMBB();
+ case AVR::SBRCRrB:
+ case AVR::SBRSRrB:
+ case AVR::SBICAb:
+ case AVR::SBISAb:
+ llvm_unreachable("unimplemented branch instructions");
+ }
+}
+
+bool AVRInstrInfo::isBranchOffsetInRange(unsigned BranchOp,
+ int64_t BrOffset) const {
+
+ switch (BranchOp) {
+ default:
+ llvm_unreachable("unexpected opcode!");
+ case AVR::JMPk:
+ case AVR::CALLk:
+ assert(BrOffset >= 0 && "offset must be absolute address");
+ return isUIntN(16, BrOffset);
+ case AVR::RCALLk:
+ case AVR::RJMPk:
+ return isIntN(13, BrOffset);
+ case AVR::BRBSsk:
+ case AVR::BRBCsk:
+ case AVR::BREQk:
+ case AVR::BRNEk:
+ case AVR::BRSHk:
+ case AVR::BRLOk:
+ case AVR::BRMIk:
+ case AVR::BRPLk:
+ case AVR::BRGEk:
+ case AVR::BRLTk:
+ return isIntN(7, BrOffset);
+ }
+}
+
} // end of namespace llvm
diff --git a/lib/Target/AVR/AVRInstrInfo.h b/lib/Target/AVR/AVRInstrInfo.h
index c5105dafe5eb5..f42d34fb28480 100644
--- a/lib/Target/AVR/AVRInstrInfo.h
+++ b/lib/Target/AVR/AVRInstrInfo.h
@@ -103,6 +103,10 @@ public:
bool
reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override;
+ MachineBasicBlock *getBranchDestBlock(const MachineInstr &MI) const override;
+
+ bool isBranchOffsetInRange(unsigned BranchOpc,
+ int64_t BrOffset) const override;
private:
const AVRRegisterInfo RI;
};
diff --git a/lib/Target/AVR/AVRInstrInfo.td b/lib/Target/AVR/AVRInstrInfo.td
index 5dd8b2c27b212..184e4d53f7c8f 100644
--- a/lib/Target/AVR/AVRInstrInfo.td
+++ b/lib/Target/AVR/AVRInstrInfo.td
@@ -1411,17 +1411,11 @@ hasSideEffects = 0 in
def LPMRdZ : FLPMX<0,
0,
(outs GPR8:$dst),
- (ins ZREGS:$z),
+ (ins ZREG:$z),
"lpm\t$dst, $z",
[]>,
Requires<[HasLPMX]>;
- def LPMWRdZ : Pseudo<(outs DREGS:$dst),
- (ins ZREGS:$z),
- "lpmw\t$dst, $z",
- []>,
- Requires<[HasLPMX]>;
-
// Load program memory, while postincrementing the Z register.
let mayLoad = 1,
Defs = [R31R30] in
@@ -1429,13 +1423,19 @@ hasSideEffects = 0 in
def LPMRdZPi : FLPMX<0,
1,
(outs GPR8:$dst),
- (ins ZREGS:$z),
+ (ins ZREG:$z),
"lpm\t$dst, $z+",
[]>,
Requires<[HasLPMX]>;
+ def LPMWRdZ : Pseudo<(outs DREGS:$dst),
+ (ins ZREG:$z),
+ "lpmw\t$dst, $z",
+ []>,
+ Requires<[HasLPMX]>;
+
def LPMWRdZPi : Pseudo<(outs DREGS:$dst),
- (ins ZREGS:$z),
+ (ins ZREG:$z),
"lpmw\t$dst, $z+",
[]>,
Requires<[HasLPMX]>;
@@ -1458,7 +1458,7 @@ hasSideEffects = 0 in
def ELPMRdZ : FLPMX<1,
0,
(outs GPR8:$dst),
- (ins ZREGS:$z),
+ (ins ZREG:$z),
"elpm\t$dst, $z",
[]>,
Requires<[HasELPMX]>;
@@ -1467,7 +1467,7 @@ hasSideEffects = 0 in
def ELPMRdZPi : FLPMX<1,
1,
(outs GPR8:$dst),
- (ins ZREGS: $z),
+ (ins ZREG: $z),
"elpm\t$dst, $z+",
[]>,
Requires<[HasELPMX]>;
@@ -1487,7 +1487,7 @@ let Uses = [R1, R0] in
let Defs = [R31R30] in
def SPMZPi : F16<0b1001010111111000,
(outs),
- (ins ZREGS:$z),
+ (ins ZREG:$z),
"spm $z+",
[]>,
Requires<[HasSPMX]>;
@@ -1564,28 +1564,28 @@ hasSideEffects = 0 in
// Read-Write-Modify (RMW) instructions.
def XCHZRd : FZRd<0b100,
(outs GPR8:$rd),
- (ins ZREGS:$z),
+ (ins ZREG:$z),
"xch\t$z, $rd",
[]>,
Requires<[SupportsRMW]>;
def LASZRd : FZRd<0b101,
(outs GPR8:$rd),
- (ins ZREGS:$z),
+ (ins ZREG:$z),
"las\t$z, $rd",
[]>,
Requires<[SupportsRMW]>;
def LACZRd : FZRd<0b110,
(outs GPR8:$rd),
- (ins ZREGS:$z),
+ (ins ZREG:$z),
"lac\t$z, $rd",
[]>,
Requires<[SupportsRMW]>;
def LATZRd : FZRd<0b111,
(outs GPR8:$rd),
- (ins ZREGS:$z),
+ (ins ZREG:$z),
"lat\t$z, $rd",
[]>,
Requires<[SupportsRMW]>;
diff --git a/lib/Target/AVR/AVRMCInstLower.cpp b/lib/Target/AVR/AVRMCInstLower.cpp
index 475dda420e892..dfefd09bc4b86 100644
--- a/lib/Target/AVR/AVRMCInstLower.cpp
+++ b/lib/Target/AVR/AVRMCInstLower.cpp
@@ -37,10 +37,22 @@ MCOperand AVRMCInstLower::lowerSymbolOperand(const MachineOperand &MO,
Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);
}
+ bool IsFunction = MO.isGlobal() && isa<Function>(MO.getGlobal());
+
if (TF & AVRII::MO_LO) {
- Expr = AVRMCExpr::create(AVRMCExpr::VK_AVR_LO8, Expr, IsNegated, Ctx);
+ if (IsFunction) {
+ // N.B. Should we use _GS fixups here to cope with >128k progmem?
+ Expr = AVRMCExpr::create(AVRMCExpr::VK_AVR_PM_LO8, Expr, IsNegated, Ctx);
+ } else {
+ Expr = AVRMCExpr::create(AVRMCExpr::VK_AVR_LO8, Expr, IsNegated, Ctx);
+ }
} else if (TF & AVRII::MO_HI) {
- Expr = AVRMCExpr::create(AVRMCExpr::VK_AVR_HI8, Expr, IsNegated, Ctx);
+ if (IsFunction) {
+ // N.B. Should we use _GS fixups here to cope with >128k progmem?
+ Expr = AVRMCExpr::create(AVRMCExpr::VK_AVR_PM_HI8, Expr, IsNegated, Ctx);
+ } else {
+ Expr = AVRMCExpr::create(AVRMCExpr::VK_AVR_HI8, Expr, IsNegated, Ctx);
+ }
} else if (TF != 0) {
llvm_unreachable("Unknown target flag on symbol operand");
}
diff --git a/lib/Target/AVR/AVRRegisterInfo.cpp b/lib/Target/AVR/AVRRegisterInfo.cpp
index 55f3f5cf428ac..249dc5512c289 100644
--- a/lib/Target/AVR/AVRRegisterInfo.cpp
+++ b/lib/Target/AVR/AVRRegisterInfo.cpp
@@ -95,7 +95,8 @@ AVRRegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC,
}
/// Fold a frame offset shared between two add instructions into a single one.
-static void foldFrameOffset(MachineInstr &MI, int &Offset, unsigned DstReg) {
+static void foldFrameOffset(MachineBasicBlock::iterator &II, int &Offset, unsigned DstReg) {
+ MachineInstr &MI = *II;
int Opcode = MI.getOpcode();
// Don't bother trying if the next instruction is not an add or a sub.
@@ -120,6 +121,7 @@ static void foldFrameOffset(MachineInstr &MI, int &Offset, unsigned DstReg) {
}
// Finally remove the instruction.
+ II++;
MI.eraseFromParent();
}
@@ -158,6 +160,8 @@ void AVRRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
unsigned DstReg = MI.getOperand(0).getReg();
assert(DstReg != AVR::R29R28 && "Dest reg cannot be the frame pointer");
+ II++; // Skip over the FRMIDX (and now MOVW) instruction.
+
// Generally, to load a frame address two add instructions are emitted that
// could get folded into a single one:
// movw r31:r30, r29:r28
@@ -166,7 +170,8 @@ void AVRRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
// to:
// movw r31:r30, r29:r28
// adiw r31:r30, 45
- foldFrameOffset(*std::next(II), Offset, DstReg);
+ if (II != MBB.end())
+ foldFrameOffset(II, Offset, DstReg);
// Select the best opcode based on DstReg and the offset size.
switch (DstReg) {
@@ -187,7 +192,7 @@ void AVRRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
}
}
- MachineInstr *New = BuildMI(MBB, std::next(II), dl, TII.get(Opcode), DstReg)
+ MachineInstr *New = BuildMI(MBB, II, dl, TII.get(Opcode), DstReg)
.addReg(DstReg, RegState::Kill)
.addImm(Offset);
New->getOperand(3).setIsDead();
diff --git a/lib/Target/AVR/AVRRegisterInfo.td b/lib/Target/AVR/AVRRegisterInfo.td
index 32650fc66751e..8162f12052be5 100644
--- a/lib/Target/AVR/AVRRegisterInfo.td
+++ b/lib/Target/AVR/AVRRegisterInfo.td
@@ -110,8 +110,6 @@ CoveredBySubRegs = 1 in
// Register Classes
//===----------------------------------------------------------------------===//
-//:TODO: use proper set instructions instead of using always "add"
-
// Main 8-bit register class.
def GPR8 : RegisterClass<"AVR", [i8], 8,
(
@@ -199,14 +197,11 @@ def PTRDISPREGS : RegisterClass<"AVR", [i16], 8,
// We have a bunch of instructions with an explicit Z register argument. We
// model this using a register class containing only the Z register.
-// :TODO: Rename to 'ZREG'.
-def ZREGS : RegisterClass<"AVR", [i16], 8, (add R31R30)>;
+def ZREG : RegisterClass<"AVR", [i16], 8, (add R31R30)>;
// Register class used for the stack read pseudo instruction.
def GPRSP: RegisterClass<"AVR", [i16], 8, (add SP)>;
-//:TODO: if we remove this we get an error in tablegen
-//:TODO: this is just a hack, remove it once add16 works!
// Status register.
def SREG : AVRReg<14, "FLAGS">, DwarfRegNum<[88]>;
def CCR : RegisterClass<"AVR", [i8], 8, (add SREG)>
diff --git a/lib/Target/AVR/AVRTargetMachine.cpp b/lib/Target/AVR/AVRTargetMachine.cpp
index 91d2a8737b870..a9d61ffc952c3 100644
--- a/lib/Target/AVR/AVRTargetMachine.cpp
+++ b/lib/Target/AVR/AVRTargetMachine.cpp
@@ -66,6 +66,7 @@ public:
bool addInstSelector() override;
void addPreSched2() override;
+ void addPreEmitPass() override;
void addPreRegAlloc() override;
};
} // namespace
@@ -115,4 +116,9 @@ void AVRPassConfig::addPreSched2() {
addPass(createAVRExpandPseudoPass());
}
+void AVRPassConfig::addPreEmitPass() {
+ // Must run branch selection immediately preceding the asm printer.
+ addPass(&BranchRelaxationPassID);
+}
+
} // end of namespace llvm
diff --git a/lib/Target/AVR/AsmParser/AVRAsmParser.cpp b/lib/Target/AVR/AsmParser/AVRAsmParser.cpp
index cf52e552978f1..5004736365c7b 100644
--- a/lib/Target/AVR/AsmParser/AVRAsmParser.cpp
+++ b/lib/Target/AVR/AsmParser/AVRAsmParser.cpp
@@ -466,6 +466,7 @@ bool AVRAsmParser::parseOperand(OperandVector &Operands) {
if (!tryParseRegisterOperand(Operands)) {
return false;
}
+ LLVM_FALLTHROUGH;
case AsmToken::LParen:
case AsmToken::Integer:
case AsmToken::Dot:
diff --git a/lib/Target/AVR/InstPrinter/AVRInstPrinter.cpp b/lib/Target/AVR/InstPrinter/AVRInstPrinter.cpp
index 316b7836df0d7..0f34b8e18ff96 100644
--- a/lib/Target/AVR/InstPrinter/AVRInstPrinter.cpp
+++ b/lib/Target/AVR/InstPrinter/AVRInstPrinter.cpp
@@ -106,7 +106,7 @@ void AVRInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
if (Op.isReg()) {
bool isPtrReg = (MOI.RegClass == AVR::PTRREGSRegClassID) ||
(MOI.RegClass == AVR::PTRDISPREGSRegClassID) ||
- (MOI.RegClass == AVR::ZREGSRegClassID);
+ (MOI.RegClass == AVR::ZREGRegClassID);
if (isPtrReg) {
O << getRegisterName(Op.getReg(), AVR::ptr);
diff --git a/lib/Target/AVR/MCTargetDesc/AVRELFStreamer.cpp b/lib/Target/AVR/MCTargetDesc/AVRELFStreamer.cpp
index 1e61eccf775f5..6d126ed622aa1 100644
--- a/lib/Target/AVR/MCTargetDesc/AVRELFStreamer.cpp
+++ b/lib/Target/AVR/MCTargetDesc/AVRELFStreamer.cpp
@@ -33,7 +33,7 @@ static unsigned getEFlagsForFeatureSet(const FeatureBitset &Features) {
EFlags |= ELF::EF_AVR_ARCH_AVR51;
else if (Features[AVR::ELFArchAVR6])
EFlags |= ELF::EF_AVR_ARCH_AVR6;
- else if (Features[AVR::ELFArchAVRTiny])
+ else if (Features[AVR::ELFArchTiny])
EFlags |= ELF::EF_AVR_ARCH_AVRTINY;
else if (Features[AVR::ELFArchXMEGA1])
EFlags |= ELF::EF_AVR_ARCH_XMEGA1;