diff --git a/Marlin/src/feature/power_loss_recovery.cpp b/Marlin/src/feature/power_loss_recovery.cpp
index 282b5d7851a966faa5967fa3c9b0290ac15abd6c..269d759ae680e96512c692855eb5c260fb52fb46 100644
--- a/Marlin/src/feature/power_loss_recovery.cpp
+++ b/Marlin/src/feature/power_loss_recovery.cpp
@@ -215,9 +215,8 @@ void PrintJobRecovery::save(const bool force/*=false*/, const bool save_queue/*=
       info.retract_hop = fwretract.current_hop;
     #endif
 
-    // Relative mode
-    info.relative_mode = relative_mode;
-    info.relative_modes_e = gcode.axis_relative_modes[E_AXIS];
+    // Relative axis modes
+    info.axis_relative = gcode.axis_relative;
 
     // Elapsed print job time
     info.print_job_elapsed = print_job_timer.duration();
@@ -392,9 +391,8 @@ void PrintJobRecovery::resume() {
   sprintf_P(cmd, PSTR("G92.9 E%s"), dtostrf(info.current_position[E_AXIS], 1, 3, str_1));
   gcode.process_subcommands_now(cmd);
 
-  // Relative mode
-  relative_mode = info.relative_mode;
-  gcode.axis_relative_modes[E_AXIS] = info.relative_modes_e;
+  // Relative axis modes
+  gcode.axis_relative = info.axis_relative;
 
   #if HAS_HOME_OFFSET || HAS_POSITION_SHIFT
     LOOP_XYZ(i) {
diff --git a/Marlin/src/feature/power_loss_recovery.h b/Marlin/src/feature/power_loss_recovery.h
index 05aa25c4db3709cdace84b6266840de24632d669..58b6c1dc7ab6e02f934a201892bde7eb0d3137ab 100644
--- a/Marlin/src/feature/power_loss_recovery.h
+++ b/Marlin/src/feature/power_loss_recovery.h
@@ -89,8 +89,8 @@ typedef struct {
     #endif
   #endif
 
-  // Relative mode
-  bool relative_mode, relative_modes_e;
+  // Relative axis modes
+  uint8_t axis_relative;
 
   // SD Filename and position
   char sd_filename[MAXPATHNAMELENGTH];
diff --git a/Marlin/src/feature/prusa_MMU2/mmu2.cpp b/Marlin/src/feature/prusa_MMU2/mmu2.cpp
index 0baa5bd95864cd0bd7cf1064c2d896d3175a7a96..ca0c03bbebea378ce18e58dbbbe2aae7e8899721 100644
--- a/Marlin/src/feature/prusa_MMU2/mmu2.cpp
+++ b/Marlin/src/feature/prusa_MMU2/mmu2.cpp
@@ -698,8 +698,6 @@ void MMU2::filament_runout() {
     }
 
     LCD_MESSAGEPGM(MSG_MMU2_EJECTING_FILAMENT);
-    const bool saved_e_relative_mode = gcode.axis_relative_modes[E_AXIS];
-    gcode.axis_relative_modes[E_AXIS] = true;
 
     enable_E0();
     current_position[E_AXIS] -= MMU2_FILAMENTCHANGE_EJECT_FEED;
@@ -735,8 +733,6 @@ void MMU2::filament_runout() {
 
     BUZZ(200, 404);
 
-    gcode.axis_relative_modes[E_AXIS] = saved_e_relative_mode;
-
     disable_E0();
 
     return true;
@@ -784,9 +780,6 @@ void MMU2::filament_runout() {
     planner.synchronize();
     enable_E0();
 
-    const bool saved_e_relative_mode = gcode.axis_relative_modes[E_AXIS];
-    gcode.axis_relative_modes[E_AXIS] = true;
-
     const E_Step* step = sequence;
 
     for (uint8_t i = 0; i < steps; i++) {
@@ -804,8 +797,6 @@ void MMU2::filament_runout() {
       step++;
     }
 
-    gcode.axis_relative_modes[E_AXIS] = saved_e_relative_mode;
-
     disable_E0();
   }
 
diff --git a/Marlin/src/gcode/gcode.cpp b/Marlin/src/gcode/gcode.cpp
index a5542322162b11078707f8a3163000f277919c50..61b75753e7a451990ce7b55a03a37db07a5c7e20 100644
--- a/Marlin/src/gcode/gcode.cpp
+++ b/Marlin/src/gcode/gcode.cpp
@@ -49,7 +49,13 @@ GcodeSuite gcode;
 
 millis_t GcodeSuite::previous_move_ms;
 
-bool GcodeSuite::axis_relative_modes[] = AXIS_RELATIVE_MODES;
+static constexpr bool ar_init[XYZE] = AXIS_RELATIVE_MODES;
+uint8_t GcodeSuite::axis_relative = (
+    (ar_init[X_AXIS] ? _BV(REL_X) : 0)
+  | (ar_init[Y_AXIS] ? _BV(REL_Y) : 0)
+  | (ar_init[Z_AXIS] ? _BV(REL_Z) : 0)
+  | (ar_init[E_AXIS] ? _BV(REL_E) : 0)
+);
 
 #if ENABLED(HOST_KEEPALIVE_FEATURE)
   GcodeSuite::MarlinBusyState GcodeSuite::busy_state = NOT_BUSY;
@@ -110,9 +116,7 @@ void GcodeSuite::get_destination_from_command() {
   LOOP_XYZE(i) {
     if ( (seen[i] = parser.seenval(axis_codes[i])) ) {
       const float v = parser.value_axis_units((AxisEnum)i);
-      destination[i] = (axis_relative_modes[i] || relative_mode)
-        ? current_position[i] + v
-        : (i == E_AXIS) ? v : LOGICAL_TO_NATIVE(v, i);
+      destination[i] = axis_is_relative(AxisEnum(i)) ? current_position[i] + v : (i == E_AXIS) ? v : LOGICAL_TO_NATIVE(v, i);
     }
     else
       destination[i] = current_position[i];
@@ -295,8 +299,8 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
         case 80: G80(); break;                                    // G80: Reset the current motion mode
       #endif
 
-      case 90: relative_mode = false; break;                      // G90: Relative Mode
-      case 91: relative_mode = true; break;                       // G91: Absolute Mode
+      case 90: set_relative_mode(false); break;                   // G90: Absolute Mode
+      case 91: set_relative_mode(true);  break;                   // G91: Relative Mode
 
       case 92: G92(); break;                                      // G92: Set current axis position(s)
 
diff --git a/Marlin/src/gcode/gcode.h b/Marlin/src/gcode/gcode.h
index 8840d40d6a41c6895d75d93375d70e525dad79b6..2d8db7ebd1e0905492b2cf9f077e64a4a0f60932 100644
--- a/Marlin/src/gcode/gcode.h
+++ b/Marlin/src/gcode/gcode.h
@@ -283,12 +283,31 @@
   #include "../feature/I2CPositionEncoder.h"
 #endif
 
+enum AxisRelative : uint8_t { REL_X, REL_Y, REL_Z, REL_E, E_MODE_ABS, E_MODE_REL };
+
 class GcodeSuite {
 public:
 
-  GcodeSuite() {}
-
-  static bool axis_relative_modes[];
+  static uint8_t axis_relative;
+
+  static inline bool axis_is_relative(const AxisEnum a) {
+    if (a == E_AXIS) {
+      if (TEST(axis_relative, E_MODE_REL)) return true;
+      if (TEST(axis_relative, E_MODE_ABS)) return false;
+    }
+    return TEST(axis_relative, a);
+  }
+  static inline void set_relative_mode(const bool rel) {
+    axis_relative = rel ? _BV(REL_X) | _BV(REL_Y) | _BV(REL_Z) | _BV(REL_E) : 0;
+  }
+  static inline void set_e_relative() {
+    CBI(axis_relative, E_MODE_ABS);
+    SBI(axis_relative, E_MODE_REL);
+  }
+  static inline void set_e_absolute() {
+    CBI(axis_relative, E_MODE_REL);
+    SBI(axis_relative, E_MODE_ABS);
+  }
 
   #if ENABLED(CNC_WORKSPACE_PLANES)
     /**
diff --git a/Marlin/src/gcode/units/M82_M83.cpp b/Marlin/src/gcode/units/M82_M83.cpp
index 110701b6b024092876e651eceed036f2ad6f52b9..11868b6ddc43ee78c1b5b130bb4894a4b01d45f6 100644
--- a/Marlin/src/gcode/units/M82_M83.cpp
+++ b/Marlin/src/gcode/units/M82_M83.cpp
@@ -25,9 +25,9 @@
 /**
  * M82: Set E codes absolute (default)
  */
-void GcodeSuite::M82() { axis_relative_modes[E_AXIS] = false; }
+void GcodeSuite::M82() { set_e_absolute(); }
 
 /**
  * M83: Set E codes relative while in Absolute Coordinates (G90) mode
  */
-void GcodeSuite::M83() { axis_relative_modes[E_AXIS] = true; }
+void GcodeSuite::M83() { set_e_relative(); }