diff --git a/Makefile b/Makefile
index 8eb8b84ce7..b255e48e0f 100644
--- a/Makefile
+++ b/Makefile
@@ -645,6 +645,9 @@ $(BUILD_DIR)/src/libultra/%.o: CFLAGS := $(EGCS_CFLAGS) -mno-abicalls
 $(BUILD_DIR)/src/libultra/%.o: CCASFLAGS := $(EGCS_CCASFLAGS)
 $(BUILD_DIR)/src/libultra/%.o: ASOPTFLAGS := $(EGCS_ASOPTFLAGS)
 
+$(BUILD_DIR)/src/libultra/libc/ll.o: OPTFLAGS := -O0
+$(BUILD_DIR)/src/libultra/libc/llcvt.o: OPTFLAGS := -O0
+
 $(BUILD_DIR)/src/libultra/os/exceptasm.o: MIPS_VERSION := -mips3
 $(BUILD_DIR)/src/libultra/os/invaldcache.o: MIPS_VERSION := -mips3
 $(BUILD_DIR)/src/libultra/os/invalicache.o: MIPS_VERSION := -mips3
diff --git a/include/libc/stdarg.h b/include/libc/stdarg.h
index ec57a0c846..7c7d2800e5 100644
--- a/include/libc/stdarg.h
+++ b/include/libc/stdarg.h
@@ -66,11 +66,12 @@ typedef char * __gnuc_va_list;
 
 /* We cast to void * and then to TYPE * because this avoids
    a warning about increasing the alignment requirement.  */
-#define va_arg(__AP, __type)                                                \
-  ((__type *) (void *) (__AP = (char *) ((__alignof__(__type) > 4           \
-                                ? ((__PTRDIFF_TYPE__)__AP + 8 - 1) & -8     \
-                                : ((__PTRDIFF_TYPE__)__AP + 4 - 1) & -4)    \
-                                         + __va_rounded_size(__type))))[-1]
+#define va_arg(__AP, __type)                                                                \
+  ((__type *) (void *) (__AP = (char *) ((__alignof__(__type) > 4                           \
+                                ? ((__PTRDIFF_TYPE__)__AP + 8 - 1) & -8                     \
+                                : ((__PTRDIFF_TYPE__)__AP + 4 - 1) & -4)                    \
+                                + __va_rounded_size (__type))),                             \
+                                *(__type *) (void *) (__AP - __va_rounded_size (__type)))
 
 typedef __gnuc_va_list va_list;
 
diff --git a/src/libultra/libc/bcmp.s b/src/libultra/libc/bcmp.s
index dcd5bc0023..9ef0746cf3 100644
--- a/src/libultra/libc/bcmp.s
+++ b/src/libultra/libc/bcmp.s
@@ -61,8 +61,8 @@ partaligncmp:
     addu    a3, a3, a0
 1:
     lwl     v0, (a0)
-    lw      v1, (a1)
     lwr     v0, 3(a0)
+    lw      v1, (a1)
     addu    a0, a0, 4
     addu    a1, a1, 4
     bne     v0, v1, cmpne
diff --git a/src/libultra/libc/bzero.s b/src/libultra/libc/bzero.s
index 9c6552f654..e1ee69e89a 100644
--- a/src/libultra/libc/bzero.s
+++ b/src/libultra/libc/bzero.s
@@ -51,8 +51,8 @@ bytezero:
     /* zero one byte at a time */
     addu    a1, a1, a0
 1:
-    sb      zero, (a0)
     addiu   a0, a0, 1
+    sb      zero, -1(a0)
     bne     a0, a1, 1b
 zerodone:
     jr      ra
diff --git a/src/libultra/libc/xldtob.c b/src/libultra/libc/xldtob.c
index a0ebe5d2d8..1a64baf041 100644
--- a/src/libultra/libc/xldtob.c
+++ b/src/libultra/libc/xldtob.c
@@ -56,7 +56,7 @@ void _Ldtob(_Pft* args, char code) {
     } else if (args->prec == 0 && (code == 'g' || code == 'G')) {
         args->prec = 1;
     }
-    err = _Ldunscale(&exp, (_Pft*)args);
+    err = _Ldunscale(&exp, args);
     if (err > 0) {
         memcpy(args->s, err == 2 ? "NaN" : "Inf", args->n1 = 3);
         return;
@@ -76,7 +76,7 @@ void _Ldtob(_Pft* args, char code) {
 
         exp = exp * 30103 / 100000 - 4;
         if (exp < 0) {
-            n = (3 - exp) & ~3;
+            n = (-exp + 3) & ~3;
             exp = -n;
             for (i = 0; n > 0; n >>= 1, i++) {
                 if ((n & 1) != 0) {
@@ -95,7 +95,7 @@ void _Ldtob(_Pft* args, char code) {
             val /= factor;
         }
 
-        gen = ((code == 'f') ? exp + 10 : 6) + args->prec;
+        gen = args->prec + ((code == 'f') ? exp + 10 : 6);
         if (gen > 0x13) {
             gen = 0x13;
         }
@@ -128,20 +128,14 @@ void _Ldtob(_Pft* args, char code) {
             --gen, --exp;
         }
 
-        nsig = ((code == 'f') ? exp + 1 : ((code == 'e' || code == 'E') ? 1 : 0)) + args->prec;
+        nsig = args->prec + ((code == 'f') ? exp + 1 : ((code == 'e' || code == 'E') ? 1 : 0));
         if (gen < nsig) {
             nsig = gen;
         }
         if (nsig > 0) {
-            char drop;
+            char drop = (nsig < gen && ptr[nsig] > '4') ? '9' : '0';
             int n2;
 
-            if (nsig < gen && ptr[nsig] > '4') {
-                drop = '9';
-            } else {
-                drop = '0';
-            }
-
             for (n2 = nsig; ptr[--n2] == drop;) {
                 nsig--;
             }
diff --git a/src/libultra/libc/xprintf.c b/src/libultra/libc/xprintf.c
index 7fba40b4c4..32a25d383c 100644
--- a/src/libultra/libc/xprintf.c
+++ b/src/libultra/libc/xprintf.c
@@ -11,7 +11,7 @@
 #define ATOI(i, a)                \
     for (i = 0; isdigit(*a); a++) \
         if (i < 999)              \
-            i = *a + i * 10 - '0';
+            i = i * 10 + *a - '0';
 
 #define PUT(fmt, _size)             \
     if (_size > 0) {                \
@@ -93,11 +93,7 @@ int _Printf(PrintCallback pfn, void* arg, const char* fmt, va_list ap) {
             }
         }
 
-        if (strchr("hlL", *s) != NULL) {
-            x.qual = *s++;
-        } else {
-            x.qual = '\0';
-        }
+        x.qual = (strchr("hlL", *s) != NULL) ? *s++ : '\0';
 
         if (x.qual == 'l' && *s == 'l') {
             x.qual = 'L';
@@ -126,7 +122,7 @@ static void _Putfld(_Pft* px, va_list* pap, char code, char* ac) {
 
     switch (code) {
         case 'c':
-            ac[px->n0++] = va_arg(*pap, unsigned int);
+            ac[px->n0++] = va_arg(*pap, int);
             break;
 
         case 'd':