aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/AVR/MCTargetDesc/AVRMCExpr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/AVR/MCTargetDesc/AVRMCExpr.cpp')
-rw-r--r--lib/Target/AVR/MCTargetDesc/AVRMCExpr.cpp32
1 files changed, 29 insertions, 3 deletions
diff --git a/lib/Target/AVR/MCTargetDesc/AVRMCExpr.cpp b/lib/Target/AVR/MCTargetDesc/AVRMCExpr.cpp
index 085afd23a83c..d4a67973af7f 100644
--- a/lib/Target/AVR/MCTargetDesc/AVRMCExpr.cpp
+++ b/lib/Target/AVR/MCTargetDesc/AVRMCExpr.cpp
@@ -29,6 +29,9 @@ const struct ModifierEntry {
{"pm_lo8", AVRMCExpr::VK_AVR_PM_LO8}, {"pm_hi8", AVRMCExpr::VK_AVR_PM_HI8},
{"pm_hh8", AVRMCExpr::VK_AVR_PM_HH8},
+
+ {"lo8_gs", AVRMCExpr::VK_AVR_LO8_GS}, {"hi8_gs", AVRMCExpr::VK_AVR_HI8_GS},
+ {"gs", AVRMCExpr::VK_AVR_GS},
};
} // end of anonymous namespace
@@ -99,24 +102,38 @@ int64_t AVRMCExpr::evaluateAsInt64(int64_t Value) const {
switch (Kind) {
case AVRMCExpr::VK_AVR_LO8:
+ Value &= 0xff;
break;
case AVRMCExpr::VK_AVR_HI8:
+ Value &= 0xff00;
Value >>= 8;
break;
case AVRMCExpr::VK_AVR_HH8:
+ Value &= 0xff0000;
Value >>= 16;
break;
case AVRMCExpr::VK_AVR_HHI8:
+ Value &= 0xff000000;
Value >>= 24;
break;
case AVRMCExpr::VK_AVR_PM_LO8:
- Value >>= 1;
+ case AVRMCExpr::VK_AVR_LO8_GS:
+ Value >>= 1; // Program memory addresses must always be shifted by one.
+ Value &= 0xff;
break;
case AVRMCExpr::VK_AVR_PM_HI8:
- Value >>= 9;
+ case AVRMCExpr::VK_AVR_HI8_GS:
+ Value >>= 1; // Program memory addresses must always be shifted by one.
+ Value &= 0xff00;
+ Value >>= 8;
break;
case AVRMCExpr::VK_AVR_PM_HH8:
- Value >>= 17;
+ Value >>= 1; // Program memory addresses must always be shifted by one.
+ Value &= 0xff0000;
+ Value >>= 16;
+ break;
+ case AVRMCExpr::VK_AVR_GS:
+ Value >>= 1; // Program memory addresses must always be shifted by one.
break;
case AVRMCExpr::VK_AVR_None:
@@ -151,6 +168,15 @@ AVR::Fixups AVRMCExpr::getFixupKind() const {
case VK_AVR_PM_HH8:
Kind = isNegated() ? AVR::fixup_hh8_ldi_pm_neg : AVR::fixup_hh8_ldi_pm;
break;
+ case VK_AVR_GS:
+ Kind = AVR::fixup_16_pm;
+ break;
+ case VK_AVR_LO8_GS:
+ Kind = AVR::fixup_lo8_ldi_gs;
+ break;
+ case VK_AVR_HI8_GS:
+ Kind = AVR::fixup_hi8_ldi_gs;
+ break;
case VK_AVR_None:
llvm_unreachable("Uninitialized expression");