Revert "Optimized string-to-number functions" (#21532)
This reverts #21484
This commit is contained in:
		
							parent
							
								
									c4b69fcddd
								
							
						
					
					
						commit
						98b2b45264
					
				@ -28,146 +28,6 @@
 | 
			
		||||
 | 
			
		||||
#include "../MarlinCore.h"
 | 
			
		||||
 | 
			
		||||
#ifdef __AVR__
 | 
			
		||||
 | 
			
		||||
  static FORCE_INLINE uint32_t mult10(uint32_t val) {
 | 
			
		||||
    uint32_t tmp = val;
 | 
			
		||||
    __asm__ __volatile__ (
 | 
			
		||||
       "add %A[tmp], %A[tmp]\n"
 | 
			
		||||
       "adc %B[tmp], %B[tmp]\n"
 | 
			
		||||
       "adc %C[tmp], %C[tmp]\n"
 | 
			
		||||
       "adc %D[tmp], %D[tmp]\n"
 | 
			
		||||
       "add %A[tmp], %A[tmp]\n"
 | 
			
		||||
       "adc %B[tmp], %B[tmp]\n"
 | 
			
		||||
       "adc %C[tmp], %C[tmp]\n"
 | 
			
		||||
       "adc %D[tmp], %D[tmp]\n"
 | 
			
		||||
       "add %A[val], %A[tmp]\n"
 | 
			
		||||
       "adc %B[val], %B[tmp]\n"
 | 
			
		||||
       "adc %C[val], %C[tmp]\n"
 | 
			
		||||
       "adc %D[val], %D[tmp]\n"
 | 
			
		||||
       "add %A[val], %A[val]\n"
 | 
			
		||||
       "adc %B[val], %B[val]\n"
 | 
			
		||||
       "adc %C[val], %C[val]\n"
 | 
			
		||||
       "adc %D[val], %D[val]\n"
 | 
			
		||||
        : [val] "+&r" (val),
 | 
			
		||||
          [tmp] "+&r" (tmp)
 | 
			
		||||
    );
 | 
			
		||||
    return val;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
  static FORCE_INLINE uint32_t mult10(uint32_t val) { return val * 10; }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// cheap base-10 strto(u)l.
 | 
			
		||||
// does not check for errors.
 | 
			
		||||
int32_t parse_int32(const char *buf) {
 | 
			
		||||
  char c;
 | 
			
		||||
 | 
			
		||||
  // Get a char, skipping leading spaces
 | 
			
		||||
  do { c = *buf++; } while (c == ' ');
 | 
			
		||||
 | 
			
		||||
  // check for sign
 | 
			
		||||
  bool is_negative = (c == '-');
 | 
			
		||||
  if (is_negative || c == '+')
 | 
			
		||||
    c = *buf++;
 | 
			
		||||
 | 
			
		||||
  // optimization for first digit (no multiplication)
 | 
			
		||||
  uint8_t uc = c - '0';
 | 
			
		||||
  if (uc > 9) return 0;
 | 
			
		||||
 | 
			
		||||
  // read unsigned value
 | 
			
		||||
  uint32_t uval = uc;
 | 
			
		||||
  while (true) {
 | 
			
		||||
    c = *buf++;
 | 
			
		||||
    uc = c - '0';
 | 
			
		||||
    if (uc > 9) break;
 | 
			
		||||
    uval = mult10(uval) + uc;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return is_negative ? -uval : uval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// cheap strtof.
 | 
			
		||||
// does not support nan/infinity or exponent notation.
 | 
			
		||||
// does not check for errors.
 | 
			
		||||
float parse_float(const char *buf) {
 | 
			
		||||
  char c;
 | 
			
		||||
 | 
			
		||||
  // Get a char, skipping leading spaces
 | 
			
		||||
  do { c = *buf++; } while (c == ' ');
 | 
			
		||||
 | 
			
		||||
  // check for sign
 | 
			
		||||
  bool is_negative = (c == '-');
 | 
			
		||||
  if (is_negative || c == '+')
 | 
			
		||||
    c = *buf++;
 | 
			
		||||
 | 
			
		||||
  // read unsigned value and decimal point
 | 
			
		||||
  uint32_t uval;
 | 
			
		||||
  uint8_t exp_dec;
 | 
			
		||||
  uint8_t uc = c - '0';
 | 
			
		||||
  if (uc <= 9) {
 | 
			
		||||
    uval = uc;
 | 
			
		||||
    exp_dec = 0;
 | 
			
		||||
  }
 | 
			
		||||
  else {
 | 
			
		||||
    if (c != '.') return 0;
 | 
			
		||||
    uval = 0;
 | 
			
		||||
    exp_dec = 1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  int8_t exp = 0;
 | 
			
		||||
  while (true) {
 | 
			
		||||
    c = *buf++;
 | 
			
		||||
    uc = c - '0';
 | 
			
		||||
    if (uc <= 9) {
 | 
			
		||||
      exp -= exp_dec;
 | 
			
		||||
      uval = mult10(uval) + uc;
 | 
			
		||||
      if (uval >= (UINT32_MAX - 9) / 10) {
 | 
			
		||||
        // overflow. keep reading digits until decimal point.
 | 
			
		||||
        while (exp_dec == 0) {
 | 
			
		||||
          c = *buf++;
 | 
			
		||||
          uc = c - '0';
 | 
			
		||||
          if (uc > 9) break;
 | 
			
		||||
          exp++;
 | 
			
		||||
        }
 | 
			
		||||
        goto overflow;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
      if (c != '.' || exp_dec != 0) break;
 | 
			
		||||
      exp_dec = 1;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // early return for 0
 | 
			
		||||
  if (uval == 0) return 0;
 | 
			
		||||
 | 
			
		||||
  overflow:
 | 
			
		||||
 | 
			
		||||
  // convert to float and apply sign
 | 
			
		||||
  float fval = uval;
 | 
			
		||||
  if (is_negative) fval *= -1;
 | 
			
		||||
 | 
			
		||||
  // apply exponent (up to 1e-15 / 1e+15)
 | 
			
		||||
  if (exp < 0) {
 | 
			
		||||
    if (exp <= -8) { fval *= 1e-8; exp += 8; }
 | 
			
		||||
    if (exp <= -4) { fval *= 1e-4; exp += 4; }
 | 
			
		||||
    if (exp <= -2) { fval *= 1e-2; exp += 2; }
 | 
			
		||||
    if (exp <= -1) { fval *= 1e-1; exp += 1; }
 | 
			
		||||
  }
 | 
			
		||||
  else if (exp > 0) {
 | 
			
		||||
    if (exp >= 8) { fval *= 1e+8; exp -= 8; }
 | 
			
		||||
    if (exp >= 4) { fval *= 1e+4; exp -= 4; }
 | 
			
		||||
    if (exp >= 2) { fval *= 1e+2; exp -= 2; }
 | 
			
		||||
    if (exp >= 1) { fval *= 1e+1; exp -= 1; }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return fval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Must be declared for allocation and to satisfy the linker
 | 
			
		||||
// Zero values need no initialization.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -42,10 +42,6 @@
 | 
			
		||||
  typedef enum : uint8_t { LINEARUNIT_MM, LINEARUNIT_INCH } LinearUnit;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int32_t parse_int32(const char *buf);
 | 
			
		||||
float parse_float(const char *buf);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * GCode parser
 | 
			
		||||
 *
 | 
			
		||||
@ -260,12 +256,29 @@ public:
 | 
			
		||||
  // The value as a string
 | 
			
		||||
  static inline char* value_string() { return value_ptr; }
 | 
			
		||||
 | 
			
		||||
  // Code value as float
 | 
			
		||||
  static inline float value_float() { return value_ptr ? parse_float(value_ptr) : 0.0; }
 | 
			
		||||
  // Float removes 'E' to prevent scientific notation interpretation
 | 
			
		||||
  static inline float value_float() {
 | 
			
		||||
    if (value_ptr) {
 | 
			
		||||
      char *e = value_ptr;
 | 
			
		||||
      for (;;) {
 | 
			
		||||
        const char c = *e;
 | 
			
		||||
        if (c == '\0' || c == ' ') break;
 | 
			
		||||
        if (c == 'E' || c == 'e') {
 | 
			
		||||
          *e = '\0';
 | 
			
		||||
          const float ret = strtof(value_ptr, nullptr);
 | 
			
		||||
          *e = c;
 | 
			
		||||
          return ret;
 | 
			
		||||
        }
 | 
			
		||||
        ++e;
 | 
			
		||||
      }
 | 
			
		||||
      return strtof(value_ptr, nullptr);
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Code value as a long or ulong
 | 
			
		||||
  static inline int32_t value_long() { return value_ptr ? parse_int32(value_ptr) : 0L; }
 | 
			
		||||
  static inline uint32_t value_ulong() { return value_ptr ? parse_int32(value_ptr) : 0UL; }
 | 
			
		||||
  static inline int32_t value_long() { return value_ptr ? strtol(value_ptr, nullptr, 10) : 0L; }
 | 
			
		||||
  static inline uint32_t value_ulong() { return value_ptr ? strtoul(value_ptr, nullptr, 10) : 0UL; }
 | 
			
		||||
 | 
			
		||||
  // Code value for use as time
 | 
			
		||||
  static inline millis_t value_millis() { return value_ulong(); }
 | 
			
		||||
 | 
			
		||||
@ -445,7 +445,7 @@ void GCodeQueue::get_serial_commands() {
 | 
			
		||||
        if (process_line_done(serial.input_state, serial.line_buffer, serial.count))
 | 
			
		||||
          continue;
 | 
			
		||||
 | 
			
		||||
        char *command = serial.line_buffer;
 | 
			
		||||
        char* command = serial.line_buffer;
 | 
			
		||||
 | 
			
		||||
        while (*command == ' ') command++;                   // Skip leading spaces
 | 
			
		||||
        char *npos = (*command == 'N') ? command : nullptr;  // Require the N parameter to start the line
 | 
			
		||||
@ -459,7 +459,7 @@ void GCodeQueue::get_serial_commands() {
 | 
			
		||||
            if (n2pos) npos = n2pos;
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          const long gcode_N = parse_int32(npos + 1);
 | 
			
		||||
          const long gcode_N = strtol(npos + 1, nullptr, 10);
 | 
			
		||||
 | 
			
		||||
          if (gcode_N != serial.last_N + 1 && !M110) {
 | 
			
		||||
            // In case of error on a serial port, don't prevent other serial port from making progress
 | 
			
		||||
@ -471,7 +471,7 @@ void GCodeQueue::get_serial_commands() {
 | 
			
		||||
          if (apos) {
 | 
			
		||||
            uint8_t checksum = 0, count = uint8_t(apos - command);
 | 
			
		||||
            while (count) checksum ^= command[--count];
 | 
			
		||||
            if (parse_int32(apos + 1) != checksum) {
 | 
			
		||||
            if (strtol(apos + 1, nullptr, 10) != checksum) {
 | 
			
		||||
              // In case of error on a serial port, don't prevent other serial port from making progress
 | 
			
		||||
              gcode_line_error(PSTR(STR_ERR_CHECKSUM_MISMATCH), p);
 | 
			
		||||
              break;
 | 
			
		||||
@ -500,7 +500,7 @@ void GCodeQueue::get_serial_commands() {
 | 
			
		||||
        if (IsStopped()) {
 | 
			
		||||
          char* gpos = strchr(command, 'G');
 | 
			
		||||
          if (gpos) {
 | 
			
		||||
            switch (parse_int32(gpos + 1)) {
 | 
			
		||||
            switch (strtol(gpos + 1, nullptr, 10)) {
 | 
			
		||||
              case 0: case 1:
 | 
			
		||||
              #if ENABLED(ARC_SUPPORT)
 | 
			
		||||
                case 2: case 3:
 | 
			
		||||
 | 
			
		||||
@ -1799,7 +1799,7 @@ void get_wifi_commands() {
 | 
			
		||||
          if (IsStopped()) {
 | 
			
		||||
          char* gpos = strchr(command, 'G');
 | 
			
		||||
          if (gpos) {
 | 
			
		||||
            switch (parse_int32(gpos + 1)) {
 | 
			
		||||
            switch (strtol(gpos + 1, nullptr, 10)) {
 | 
			
		||||
              case 0 ... 1:
 | 
			
		||||
              #if ENABLED(ARC_SUPPORT)
 | 
			
		||||
                case 2 ... 3:
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user