Merge change 21737 into eclair

* changes:
  Added -s flag to ls.
diff --git a/fastboot/usb_linux.c b/fastboot/usb_linux.c
index 06c62b8..3b40ba7 100644
--- a/fastboot/usb_linux.c
+++ b/fastboot/usb_linux.c
@@ -51,7 +51,9 @@
 
 #include "usb.h"
 
-#if TRACE_USB
+#define MAX_RETRIES 5
+
+#ifdef TRACE_USB
 #define DBG1(x...) fprintf(stderr, x)
 #define DBG(x...) fprintf(stderr, x)
 #else
@@ -303,7 +305,7 @@
     unsigned char *data = (unsigned char*) _data;
     unsigned count = 0;
     struct usbdevfs_bulktransfer bulk;
-    int n;
+    int n, retry;
 
     if(h->ep_in == 0) {
         return -1;
@@ -316,16 +318,20 @@
         bulk.len = xfer;
         bulk.data = data;
         bulk.timeout = 0;
-        
-        DBG("[ usb read %d fd = %d], fname=%s\n", xfer, h->desc, h->fname);
-        n = ioctl(h->desc, USBDEVFS_BULK, &bulk);
-        DBG("[ usb read %d ] = %d, fname=%s\n", xfer, n, h->fname);
+        retry = 0;
 
-        if(n < 0) {
-            DBG1("ERROR: n = %d, errno = %d (%s)\n",
-                n, errno, strerror(errno));
-            return -1;
+        do{
+           DBG("[ usb read %d fd = %d], fname=%s\n", xfer, h->desc, h->fname);
+           n = ioctl(h->desc, USBDEVFS_BULK, &bulk);
+           DBG("[ usb read %d ] = %d, fname=%s, Retry %d \n", xfer, n, h->fname, retry);
+
+           if( n < 0 ) {
+            DBG1("ERROR: n = %d, errno = %d (%s)\n",n, errno, strerror(errno));
+            if ( ++retry > MAX_RETRIES ) return -1;
+            sleep( 1 );
+           }
         }
+        while( n < 0 );
 
         count += n;
         len -= n;
diff --git a/init/devices.c b/init/devices.c
index 4ffdf47..f4a3595 100644
--- a/init/devices.c
+++ b/init/devices.c
@@ -131,6 +131,7 @@
     { "/dev/bma150",        0640,   AID_COMPASS,    AID_SYSTEM,     0 },
     { "/dev/cm3602",        0640,   AID_COMPASS,    AID_SYSTEM,     0 },
     { "/dev/akm8976_pffd",  0640,   AID_COMPASS,    AID_SYSTEM,     0 },
+    { "/dev/lightsensor",   0640,   AID_SYSTEM,     AID_SYSTEM,     0 },
     { "/dev/msm_pcm_out",   0660,   AID_SYSTEM,     AID_AUDIO,      1 },
     { "/dev/msm_pcm_in",    0660,   AID_SYSTEM,     AID_AUDIO,      1 },
     { "/dev/msm_pcm_ctl",   0660,   AID_SYSTEM,     AID_AUDIO,      1 },
diff --git a/libacc/acc.cpp b/libacc/acc.cpp
index 684d807..1990dd6 100644
--- a/libacc/acc.cpp
+++ b/libacc/acc.cpp
@@ -43,6 +43,10 @@
 #include "disassem.h"
 #endif
 
+#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
+#define ARM_USE_VFP
+#endif
+
 #include <acc/acc.h>
 
 #define LOG_API(...) do {} while(0)
@@ -684,7 +688,13 @@
 
     class ARMCodeGenerator : public CodeGenerator {
     public:
-        ARMCodeGenerator() {}
+        ARMCodeGenerator() {
+#ifdef ARM_USE_VFP
+        	LOGD("Using ARM VFP hardware floating point.");
+#else
+        	LOGD("Using ARM soft floating point.");
+#endif
+        }
 
         virtual ~ARMCodeGenerator() {}
 
@@ -721,6 +731,22 @@
             }
             *(char*) (localVariableAddress) = localVariableSize;
 
+#ifdef ARM_USE_VFP
+            {
+            	Type* pReturnType = pDecl->pHead;
+            	switch(pReturnType->tag) {
+            	case TY_FLOAT:
+            		o4(0xEE170A90); // fmrs	r0, s15
+            		break;
+            	case TY_DOUBLE:
+            		o4(0xEC510B17); // fmrrd r0, r1, d7
+            		break;
+            	default:
+            		break;
+            	}
+            }
+#endif
+
             // sp -> locals .... fp -> oldfp, retadr, arg0, arg1, ...
             o4(0xE1A0E00B); // mov lr, fp
             o4(0xE59BB000); // ldr fp, [fp]
@@ -756,10 +782,18 @@
 
             switch (pType->tag) {
             case TY_FLOAT:
+#ifdef ARM_USE_VFP
+                o4(0xEDD07A00);      // flds	s15, [r0]
+#else
                 o4(0xE5900000);      // ldr r0, [r0]
+#endif
                 break;
             case TY_DOUBLE:
+#ifdef ARM_USE_VFP
+                o4(0xED907B00);      // fldd	d7, [r0]
+#else
                 o4(0xE1C000D0);      // ldrd r0, [r0]
+#endif
                 break;
             default:
                 assert(false);
@@ -777,15 +811,27 @@
             TypeTag tagR0 = pR0Type->tag;
             switch(tagR0) {
                 case TY_FLOAT:
+#ifdef ARM_USE_VFP
+                	o4(0xEEF57A40); // fcmpzs	s15
+                	o4(0xEEF1FA10); // fmstat
+#else
                     callRuntime((void*) runtime_is_non_zero_f);
+                    o4(0xE3500000); // cmp r0,#0
+#endif
                     break;
                 case TY_DOUBLE:
+#ifdef ARM_USE_VFP
+                	o4(0xEEB57B40); // fcmpzd	d7
+                	o4(0xEEF1FA10); // fmstat
+#else
                     callRuntime((void*) runtime_is_non_zero_d);
+                    o4(0xE3500000); // cmp r0,#0
+#endif
                     break;
                 default:
+                    o4(0xE3500000); // cmp r0,#0
                     break;
             }
-            o4(0xE3500000); // cmp r0,#0
             int branch = l ? 0x1A000000 : 0x0A000000; // bne : beq
             return o4(branch | encodeAddress(t));
         }
@@ -829,6 +875,39 @@
                 }
             } else if (tagR0 == TY_DOUBLE || tagTOS == TY_DOUBLE) {
                 setupDoubleArgs();
+#ifdef ARM_USE_VFP
+                o4(0xEEB46BC7); // 		fcmped	d6, d7
+           	    o4(0xEEF1FA10); // fmstat
+                switch(op) {
+                case OP_EQUALS:
+                    o4(0x03A00001); // moveq r0,#1
+                    o4(0x13A00000); // movne r0,#0
+                    break;
+                case OP_NOT_EQUALS:
+                    o4(0x03A00000); // moveq r0,#0
+                    o4(0x13A00001); // movne r0,#1
+                    break;
+                case OP_LESS_EQUAL:
+                    o4(0xD3A00001); // movle r0,#1
+                    o4(0xC3A00000); // movgt r0,#0
+                    break;
+                case OP_GREATER:
+                    o4(0xD3A00000); // movle r0,#0
+                    o4(0xC3A00001); // movgt r0,#1
+                    break;
+                case OP_GREATER_EQUAL:
+                    o4(0xA3A00001); // movge r0,#1
+                    o4(0xB3A00000); // movlt r0,#0
+                    break;
+                case OP_LESS:
+                    o4(0xA3A00000); // movge r0,#0
+                    o4(0xB3A00001); // movlt r0,#1
+                    break;
+                default:
+                    error("Unknown comparison op %d", op);
+                    break;
+                }
+#else
                 switch(op) {
                     case OP_EQUALS:
                         callRuntime((void*) runtime_cmp_eq_dd);
@@ -852,8 +931,42 @@
                         error("Unknown comparison op %d", op);
                         break;
                 }
+#endif
             } else {
                 setupFloatArgs();
+#ifdef ARM_USE_VFP
+                o4(0xEEB47AE7); // fcmpes s14, s15
+           	    o4(0xEEF1FA10); // fmstat
+                switch(op) {
+                case OP_EQUALS:
+                    o4(0x03A00001); // moveq r0,#1
+                    o4(0x13A00000); // movne r0,#0
+                    break;
+                case OP_NOT_EQUALS:
+                    o4(0x03A00000); // moveq r0,#0
+                    o4(0x13A00001); // movne r0,#1
+                    break;
+                case OP_LESS_EQUAL:
+                    o4(0xD3A00001); // movle r0,#1
+                    o4(0xC3A00000); // movgt r0,#0
+                    break;
+                case OP_GREATER:
+                    o4(0xD3A00000); // movle r0,#0
+                    o4(0xC3A00001); // movgt r0,#1
+                    break;
+                case OP_GREATER_EQUAL:
+                    o4(0xA3A00001); // movge r0,#1
+                    o4(0xB3A00000); // movlt r0,#0
+                    break;
+                case OP_LESS:
+                    o4(0xA3A00000); // movge r0,#0
+                    o4(0xB3A00001); // movlt r0,#1
+                    break;
+                default:
+                    error("Unknown comparison op %d", op);
+                    break;
+                }
+#else
                 switch(op) {
                     case OP_EQUALS:
                         callRuntime((void*) runtime_cmp_eq_ff);
@@ -877,6 +990,7 @@
                         error("Unknown comparison op %d", op);
                         break;
                 }
+#endif
             }
             setR0Type(mkpInt);
         }
@@ -979,18 +1093,35 @@
                 Type* pResultType = tagR0 > tagTOS ? pR0Type : pTOSType;
                 if (pResultType->tag == TY_DOUBLE) {
                     setupDoubleArgs();
+
                     switch(op) {
                     case OP_MUL:
-                        callRuntime((void*) runtime_op_mul_dd);
+#ifdef ARM_USE_VFP
+                    	o4(0xEE267B07); // fmuld d7, d6, d7
+#else
+                    	callRuntime((void*) runtime_op_mul_dd);
+#endif
                         break;
                     case OP_DIV:
+#ifdef ARM_USE_VFP
+                    	o4(0xEE867B07); // fdivd d7, d6, d7
+#else
                         callRuntime((void*) runtime_op_div_dd);
+#endif
                         break;
                     case OP_PLUS:
+#ifdef ARM_USE_VFP
+                    	o4(0xEE367B07); // faddd d7, d6, d7
+#else
                         callRuntime((void*) runtime_op_add_dd);
+#endif
                         break;
                     case OP_MINUS:
+#ifdef ARM_USE_VFP
+                    	o4(0xEE367B47); // fsubd d7, d6, d7
+#else
                         callRuntime((void*) runtime_op_sub_dd);
+#endif
                         break;
                     default:
                         error("Unsupported binary floating operation %d\n", op);
@@ -1000,16 +1131,32 @@
                     setupFloatArgs();
                     switch(op) {
                     case OP_MUL:
+#ifdef ARM_USE_VFP
+                    	o4(0xEE677A27); // fmuls s15, s14, s15
+#else
                         callRuntime((void*) runtime_op_mul_ff);
+#endif
                         break;
                     case OP_DIV:
+#ifdef ARM_USE_VFP
+                    	o4(0xEEC77A27); // fdivs s15, s14, s15
+#else
                         callRuntime((void*) runtime_op_div_ff);
+#endif
                         break;
                     case OP_PLUS:
+#ifdef ARM_USE_VFP
+                    	o4(0xEE777A27); // fadds s15, s14, s15
+#else
                         callRuntime((void*) runtime_op_add_ff);
+#endif
                         break;
                     case OP_MINUS:
+#ifdef ARM_USE_VFP
+                    	o4(0xEE777A67); // fsubs s15, s14, s15
+#else
                         callRuntime((void*) runtime_op_sub_ff);
+#endif
                         break;
                     default:
                         error("Unsupported binary floating operation %d\n", op);
@@ -1034,10 +1181,24 @@
                         o4(0x13A00000); // movne r0,#0
                         break;
                     case TY_FLOAT:
-                        callRuntime((void*) runtime_is_zero_f);
+#ifdef ARM_USE_VFP
+                        o4(0xEEF57A40); // fcmpzs s15
+                        o4(0xEEF1FA10); // fmstat
+                        o4(0x03A00001); // moveq r0,#1
+                        o4(0x13A00000); // movne r0,#0
+#else
+						callRuntime((void*) runtime_is_zero_f);
+#endif
                         break;
                     case TY_DOUBLE:
-                        callRuntime((void*) runtime_is_zero_d);
+#ifdef ARM_USE_VFP
+                        o4(0xEEB57B40); // fcmpzd d7
+                        o4(0xEEF1FA10); // fmstat
+                        o4(0x03A00001); // moveq r0,#1
+                        o4(0x13A00000); // movne r0,#0
+#else
+                    	callRuntime((void*) runtime_is_zero_d);
+#endif
                         break;
                     default:
                         error("gUnaryCmp unsupported type");
@@ -1070,9 +1231,17 @@
                     switch (op) {
                         case OP_MINUS:
                             if (tag == TY_FLOAT) {
+#ifdef ARM_USE_VFP
+                            	o4(0xEEF17A67); // fnegs	s15, s15
+#else
                                 callRuntime((void*) runtime_op_neg_f);
+#endif
                             } else {
+#ifdef ARM_USE_VFP
+                            	o4(0xEEB17B47); // fnegd	d7, d7
+#else
                                 callRuntime((void*) runtime_op_neg_d);
+#endif
                             }
                             break;
                         case OP_BIT_NOT:
@@ -1092,6 +1261,23 @@
         virtual void pushR0() {
             Type* pR0Type = getR0Type();
             TypeTag r0ct = collapseType(pR0Type->tag);
+
+#ifdef ARM_USE_VFP
+            switch (r0ct ) {
+            case TY_FLOAT:
+            	o4(0xED6D7A01); // fstmfds   sp!,{s15}
+                mStackUse += 4;
+            	break;
+            case TY_DOUBLE:
+            	o4(0xED2D7B02); // fstmfdd   sp!,{d7}
+                mStackUse += 8;
+            	break;
+            default:
+                o4(0xE92D0001);  // stmfd   sp!,{r0}
+                mStackUse += 4;
+            }
+#else
+
             if (r0ct != TY_DOUBLE) {
                     o4(0xE92D0001);  // stmfd   sp!,{r0}
                     mStackUse += 4;
@@ -1099,6 +1285,7 @@
                     o4(0xE92D0003);  // stmfd   sp!,{r0,r1}
                     mStackUse += 8;
             }
+#endif
             pushType();
             LOG_STACK("pushR0: %d\n", mStackUse);
         }
@@ -1123,7 +1310,13 @@
 
         virtual void popR0() {
             Type* pTOSType = getTOSType();
-            switch (collapseType(pTOSType->tag)){
+            TypeTag tosct = collapseType(pTOSType->tag);
+#ifdef ARM_USE_VFP
+            if (tosct == TY_FLOAT || tosct == TY_DOUBLE) {
+            	error("Unsupported popR0 float/double");
+            }
+#endif
+            switch (tosct){
                 case TY_INT:
                 case TY_FLOAT:
                     o4(0xE8BD0001);  // ldmfd   sp!,{r0}
@@ -1152,9 +1345,15 @@
             switch (pDestType->tag) {
                 case TY_POINTER:
                 case TY_INT:
-                case TY_FLOAT:
                     o4(0xE5820000); // str r0, [r2]
                     break;
+                case TY_FLOAT:
+#ifdef ARM_USE_VFP
+                	o4(0xEDC27A00); // fsts	s15, [r2, #0]
+#else
+                    o4(0xE5820000); // str r0, [r2]
+#endif
+                    break;
                 case TY_SHORT:
                     o4(0xE1C200B0); // strh r0, [r2]
                     break;
@@ -1162,7 +1361,11 @@
                     o4(0xE5C20000); // strb r0, [r2]
                     break;
                 case TY_DOUBLE:
+#ifdef ARM_USE_VFP
+                	o4(0xED827B00); // fstd	d7, [r2, #0]
+#else
                     o4(0xE1C200F0); // strd r0, [r2]
+#endif
                     break;
                 default:
                     error("storeR0ToTOS: unimplemented type %d",
@@ -1179,9 +1382,15 @@
             switch (tag) {
                 case TY_POINTER:
                 case TY_INT:
-                case TY_FLOAT:
                     o4(0xE5900000); // ldr r0, [r0]
                     break;
+                case TY_FLOAT:
+#ifdef ARM_USE_VFP
+                    o4(0xEDD07A00); // flds	s15, [r0, #0]
+#else
+                    o4(0xE5900000); // ldr r0, [r0]
+#endif
+                    break;
                 case TY_SHORT:
                     o4(0xE1D000F0); // ldrsh r0, [r0]
                     break;
@@ -1189,7 +1398,11 @@
                     o4(0xE5D00000); // ldrb r0, [r0]
                     break;
                 case TY_DOUBLE:
+#ifdef ARM_USE_VFP
+                    o4(0xED907B00); // fldd	d7, [r0, #0]
+#else
                     o4(0xE1C000D0); // ldrd   r0, [r0]
+#endif
                     break;
                 case TY_ARRAY:
                     pNewType = pNewType->pTail;
@@ -1272,25 +1485,55 @@
                 TypeTag destTag = collapseType(pType->tag);
                 if (r0Tag == TY_INT) {
                     if (destTag == TY_FLOAT) {
+#ifdef ARM_USE_VFP
+                    	o4(0xEE070A90); // fmsr	s15, r0
+                    	o4(0xEEF87AE7); // fsitos s15, s15
+
+#else
                         callRuntime((void*) runtime_int_to_float);
+#endif
                     } else {
                         assert(destTag == TY_DOUBLE);
+#ifdef ARM_USE_VFP
+                    	o4(0xEE070A90); // fmsr s15, r0
+                    	o4(0xEEB87BE7); // fsitod d7, s15
+
+#else
                         callRuntime((void*) runtime_int_to_double);
+#endif
                     }
                 } else if (r0Tag == TY_FLOAT) {
                     if (destTag == TY_INT) {
+#ifdef ARM_USE_VFP
+                    	o4(0xEEFD7AE7); // ftosizs s15, s15
+                    	o4(0xEE170A90); // fmrs r0, s15
+#else
                         callRuntime((void*) runtime_float_to_int);
+#endif
                     } else {
                         assert(destTag == TY_DOUBLE);
+#ifdef ARM_USE_VFP
+                    	o4(0xEEB77AE7); // fcvtds	d7, s15
+#else
                         callRuntime((void*) runtime_float_to_double);
+#endif
                     }
                 } else {
                     assert (r0Tag == TY_DOUBLE);
                     if (destTag == TY_INT) {
+#ifdef ARM_USE_VFP
+                    	o4(0xEEFD7BC7); // ftosizd s15, d7
+                    	o4(0xEE170A90); // fmrs r0, s15
+#else
                         callRuntime((void*) runtime_double_to_int);
+#endif
                     } else {
                         assert(destTag == TY_FLOAT);
+#ifdef ARM_USE_VFP
+                        o4(0xEEF77BC7); // fcvtsd s15, d7
+#else
                         callRuntime((void*) runtime_double_to_float);
+#endif
                     }
                 }
             }
@@ -1305,9 +1548,37 @@
             convertR0(pArgType);
             Type* pR0Type = getR0Type();
             TypeTag r0ct = collapseType(pR0Type->tag);
+#ifdef ARM_USE_VFP
             switch(r0ct) {
                 case TY_INT:
-                case TY_FLOAT:
+                    if (l < 0 || l > 4096-4) {
+                        error("l out of range for stack offset: 0x%08x", l);
+                    }
+                    o4(0xE58D0000 | l); // str r0, [sp, #l]
+                    return 4;
+				case TY_FLOAT:
+                    if (l < 0 || l > 1020 || (l & 3)) {
+                        error("l out of range for stack offset: 0x%08x", l);
+                    }
+                    o4(0xEDCD7A00 | (l >> 2)); // fsts	s15, [sp, #l]
+                    return 4;
+                case TY_DOUBLE: {
+                    // Align to 8 byte boundary
+                    int l2 = (l + 7) & ~7;
+                    if (l2 < 0 || l2 > 1020 || (l2 & 3)) {
+                        error("l out of range for stack offset: 0x%08x", l);
+                    }
+                    o4(0xED8D7B00 | (l2 >> 2)); // fstd	d7, [sp, #l2]
+                    return (l2 - l) + 8;
+                }
+                default:
+                    assert(false);
+                    return 0;
+            }
+#else
+            switch(r0ct) {
+                case TY_INT:
+				case TY_FLOAT:
                     if (l < 0 || l > 4096-4) {
                         error("l out of range for stack offset: 0x%08x", l);
                     }
@@ -1327,6 +1598,7 @@
                     assert(false);
                     return 0;
             }
+#endif
         }
 
         virtual void endFunctionCallArguments(Type* pDecl, int a, int l) {
@@ -1370,7 +1642,6 @@
         virtual void callIndirect(int l, Type* pFunc) {
             assert(pFunc->tag == TY_FUNC);
             popType(); // Get rid of indirect fn pointer type
-            setR0Type(pFunc->pHead);
             int argCount = l >> 2;
             int poppedArgs = argCount > 4 ? 4 : argCount;
             int adjustedL = l - (poppedArgs << 2) + mStackAlignmentAdjustment;
@@ -1379,6 +1650,20 @@
             }
             o4(0xE59DC000 | (0xfff & adjustedL)); // ldr    r12, [sp,#adjustedL]
             o4(0xE12FFF3C); // blx r12
+            Type* pReturnType = pFunc->pHead;
+            setR0Type(pReturnType);
+#ifdef ARM_USE_VFP
+            switch(pReturnType->tag) {
+            case TY_FLOAT:
+            	o4(0xEE070A90); // fmsr s15, r0
+            	break;
+            case TY_DOUBLE:
+            	o4(0xEC410B17); // fmdrr d7, r0, r1
+            	break;
+            default:
+            	break;
+            }
+#endif
         }
 
         virtual void adjustStackAfterCall(Type* pDecl, int l, bool isIndirect) {
@@ -1594,7 +1879,7 @@
             popType();
         }
 
-        /* Pop TOS to R1
+        /* Pop TOS to R1 (use s14 if VFP)
          * Make sure both R0 and TOS are floats. (Could be ints)
          * We know that at least one of R0 and TOS is already a float
          */
@@ -1605,26 +1890,41 @@
             TypeTag tagTOS = collapseType(pTOSType->tag);
             if (tagR0 != TY_FLOAT) {
                 assert(tagR0 == TY_INT);
+#ifdef ARM_USE_VFP
+            	o4(0xEE070A90); // fmsr	s15, r0
+            	o4(0xEEF87AE7); // fsitos s15, s15
+#else
                 callRuntime((void*) runtime_int_to_float);
+#endif
             }
             if (tagTOS != TY_FLOAT) {
                 assert(tagTOS == TY_INT);
                 assert(tagR0 == TY_FLOAT);
+#ifdef ARM_USE_VFP
+                o4(0xECBD7A01); // fldmfds sp!, {s14}
+            	o4(0xEEB87AC7); // fsitos s14, s14
+#else
                 o4(0xE92D0001);  // stmfd   sp!,{r0}  // push R0
                 o4(0xE59D0004);  // ldr     r0, [sp, #4]
                 callRuntime((void*) runtime_int_to_float);
                 o4(0xE1A01000);  // mov r1, r0
                 o4(0xE8BD0001);  // ldmfd   sp!,{r0}  // pop R0
                 o4(0xE28DD004);  // add sp, sp, #4 // Pop sp
+#endif
             } else {
                 // Pop TOS
+#ifdef ARM_USE_VFP
+                o4(0xECBD7A01); // fldmfds sp!, {s14}
+
+#else
                 o4(0xE8BD0002);  // ldmfd   sp!,{r1}
+#endif
             }
             mStackUse -= 4;
             popType();
         }
 
-        /* Pop TOS into R2..R3
+        /* Pop TOS into R2..R3 (use D6 if VFP)
          * Make sure both R0 and TOS are doubles. Could be floats or ints.
          * We know that at least one of R0 and TOS are already a double.
          */
@@ -1636,13 +1936,33 @@
             TypeTag tagTOS = collapseType(pTOSType->tag);
             if (tagR0 != TY_DOUBLE) {
                 if (tagR0 == TY_INT) {
+#ifdef ARM_USE_VFP
+					o4(0xEE070A90); // fmsr s15, r0
+					o4(0xEEB87BE7); // fsitod d7, s15
+
+#else
                     callRuntime((void*) runtime_int_to_double);
+#endif
                 } else {
                     assert(tagR0 == TY_FLOAT);
+#ifdef ARM_USE_VFP
+                    o4(0xEEB77AE7); // fcvtds	d7, s15
+#else
                     callRuntime((void*) runtime_float_to_double);
+#endif
                 }
             }
             if (tagTOS != TY_DOUBLE) {
+#ifdef ARM_USE_VFP
+                if (tagTOS == TY_INT) {
+                    o4(0xECFD6A01);  // fldmfds sp!,{s13}
+					o4(0xEEB86BE6);  // fsitod  d6, s13
+                } else {
+                    assert(tagTOS == TY_FLOAT);
+                    o4(0xECFD6A01);  // fldmfds sp!,{s13}
+                    o4(0xEEB76AE6);  // fcvtds	d6, s13
+                }
+#else
                 o4(0xE92D0003);  // stmfd   sp!,{r0,r1}  // push r0,r1
                 o4(0xE59D0008);  // ldr     r0, [sp, #8]
                 if (tagTOS == TY_INT) {
@@ -1655,9 +1975,14 @@
                 o4(0xE1A03001);  // mov r3, r1
                 o4(0xE8BD0003);  // ldmfd   sp!,{r0, r1}  // Restore R0
                 o4(0xE28DD004);  // add sp, sp, #4 // Pop sp
+#endif
                 mStackUse -= 4;
             } else {
+#ifdef ARM_USE_VFP
+            	o4(0xECBD6B02);  // fldmfdd	sp!, {d6}
+#else
                 o4(0xE8BD000C);  // ldmfd   sp!,{r2,r3}
+#endif
                 mStackUse -= 8;
             }
             popType();
@@ -1696,6 +2021,8 @@
             return a % b;
         }
 
+#ifndef ARM_USE_VFP
+
         // Comparison to zero
 
         static int runtime_is_non_zero_f(float a) {
@@ -1838,6 +2165,8 @@
             return -a;
         }
 
+#endif
+
         static const int STACK_ALIGNMENT = 8;
         int mStackUse;
         // This variable holds the amount we adjusted the stack in the most
@@ -2677,9 +3006,9 @@
             return mpBase->leaForward(ea, pPointerType);
         }
 
-        virtual void convertR0(Type* pType){
-            fprintf(stderr, "convertR0(pType tag=%d)\n",  pType->tag);
-            mpBase->convertR0(pType);
+        virtual void convertR0Imp(Type* pType, bool isCast){
+            fprintf(stderr, "convertR0(pType tag=%d, %d)\n",  pType->tag, isCast);
+            mpBase->convertR0Imp(pType, isCast);
         }
 
         virtual int beginFunctionCallArguments() {
@@ -3292,6 +3621,7 @@
     intptr_t loc; // local variable index
     char* glo;  // global variable index
     String mTokenString;
+    bool mbSuppressMacroExpansion;
     char* dptr; // Macro state: Points to macro text during macro playback.
     int dch;    // Macro state: Saves old value of ch during a macro playback.
     char* pGlobalBase;
@@ -3726,14 +4056,16 @@
                 inp();
             }
             tok = mTokenTable.intern(mTokenString.getUnwrapped(), mTokenString.len());
-            // Is this a macro?
-            char* pMacroDefinition = mTokenTable[tok].mpMacroDefinition;
-            if (pMacroDefinition) {
-                // Yes, it is a macro
-                dptr = pMacroDefinition;
-                dch = ch;
-                inp();
-                next();
+            if (! mbSuppressMacroExpansion) {
+                // Is this a macro?
+                char* pMacroDefinition = mTokenTable[tok].mpMacroDefinition;
+                if (pMacroDefinition) {
+                    // Yes, it is a macro
+                    dptr = pMacroDefinition;
+                    dch = ch;
+                    inp();
+                    next();
+                }
             }
         } else {
             inp();
@@ -3809,12 +4141,11 @@
     }
 
     void doDefine() {
+        mbSuppressMacroExpansion = true;
         next();
+        mbSuppressMacroExpansion = false;
         tokenid_t name = tok;
         String* pName = new String();
-        while (isspace(ch)) {
-            inp();
-        }
         if (ch == '(') {
             delete pName;
             error("Defines with arguments not supported");
@@ -3824,8 +4155,20 @@
             inp();
         }
         String value;
+        bool appendToValue = true;
         while (ch != '\n' && ch != EOF) {
-            value.append(ch);
+            // Check for '//' comments.
+            if (appendToValue && ch == '/') {
+                inp();
+                if (ch == '/') {
+                    appendToValue = false;
+                } else {
+                    value.append('/');
+                }
+            }
+            if (appendToValue && ch != EOF) {
+                value.append(ch);
+            }
             inp();
         }
         char* pDefn = (char*)mGlobalArena.alloc(value.len() + 1);
@@ -4877,11 +5220,15 @@
                     int argCount = 0;
                     for (Type* pP = pDecl->pTail; pP; pP = pP->pTail) {
                         Type* pArg = pP->pHead;
-                        addLocalSymbol(pArg);
+                        if (pArg->id) {
+                            addLocalSymbol(pArg);
+                        }
                         /* read param name and compute offset */
                         size_t alignment = pGen->stackAlignmentOf(pArg);
                         a = (a + alignment - 1) & ~ (alignment-1);
-                        VI(pArg->id)->pAddress = (void*) a;
+                        if (pArg->id) {
+                            VI(pArg->id)->pAddress = (void*) a;
+                        }
                         a = a + pGen->stackSizeOf(pArg);
                         argCount++;
                     }
@@ -4948,6 +5295,7 @@
         mCompileResult = 0;
         mLineNumber = 1;
         mbBumpLine = false;
+        mbSuppressMacroExpansion = false;
     }
 
     void setArchitecture(const char* architecture) {
diff --git a/libacc/tests/data/defines.c b/libacc/tests/data/defines.c
new file mode 100644
index 0000000..6cb6f7e
--- /dev/null
+++ b/libacc/tests/data/defines.c
@@ -0,0 +1,9 @@
+// Simple tests of the C preprocessor
+
+#define A 1
+#define A (4 / 2)
+#define B 1 // This is a comment. With a / in it.
+
+int main() {
+    return A + B;
+}
diff --git a/libacc/tests/data/funcargs.c b/libacc/tests/data/funcargs.c
new file mode 100644
index 0000000..1dce226
--- /dev/null
+++ b/libacc/tests/data/funcargs.c
@@ -0,0 +1,8 @@
+int f(int a,int, int c) {
+    return a + c;
+}
+
+int main() {
+    return f(1,2,3);
+}
+
diff --git a/libacc/tests/test b/libacc/tests/test
index ef10500..8fd6916 100755
--- a/libacc/tests/test
+++ b/libacc/tests/test
@@ -2,5 +2,5 @@
 
 SCRIPT_DIR=`dirname $BASH_SOURCE`
 cd $SCRIPT_DIR
-python test.py
+python test.py "$@"
 
diff --git a/libacc/tests/test.py b/libacc/tests/test.py
index 9691c27..ab85f10 100644
--- a/libacc/tests/test.py
+++ b/libacc/tests/test.py
@@ -4,9 +4,32 @@
 import unittest
 import subprocess
 import os
-import sets
+import sys
 
 gArmInitialized = False
+gUseArm = True
+gUseX86 = True
+gRunOTCCOutput = True
+
+
+def parseArgv():
+    global gUseArm
+    global gUseX86
+    global gRunOTCCOutput
+    for arg in sys.argv[1:]:
+        if arg == "--noarm":
+            print "--noarm: not testing ARM"
+            gUseArm = False
+        elif arg == "--nox86":
+            print "--nox86: not testing x86"
+            gUseX86 = False
+        elif arg == "--norunotcc":
+            print "--norunotcc detected, not running OTCC output"
+            gRunOTCCOutput = False
+        else:
+            print "Unknown parameter: ", arg
+            raise "Unknown parameter"
+    sys.argv = sys.argv[0:1]
 
 def compile(args):
     proc = subprocess.Popen(["acc"] + args, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
@@ -131,11 +154,13 @@
 
     def compileCheck(self, args, stdErrResult, stdOutResult="",
                      targets=['arm', 'x86']):
-        targetSet = sets.ImmutableSet(targets)
-        if False and 'x86' in targetSet:
+        global gUseArm
+        global gUseX86
+        targetSet = frozenset(targets)
+        if gUseX86 and 'x86' in targetSet:
             out, err = compile(args)
             self.checkResult(out, err, stdErrResult, stdOutResult)
-        if 'arm' in targetSet:
+        if gUseArm and 'arm' in targetSet:
             out = compileArm(rewritePaths(args))
             self.checkResult(out, "", stdErrResult, stdOutResult)
 
@@ -157,13 +182,17 @@
         "Executing compiled code:\nresult: 13\n", "Hello, world\n")
 
     def testRunOTCCANSI(self):
-        self.compileCheck(["-R", "data/otcc-ansi.c", "data/returnval.c"],
-            "Executing compiled code:\notcc-ansi.c: About to execute compiled code:\natcc-ansi.c: result: 42\nresult: 42\n", "",
-             ['x86'])
+        global gRunOTCCOutput
+        if gRunOTCCOutput:
+            self.compileCheck(["-R", "data/otcc-ansi.c", "data/returnval.c"],
+                "Executing compiled code:\notcc-ansi.c: About to execute compiled code:\natcc-ansi.c: result: 42\nresult: 42\n", "",
+                 ['x86'])
 
     def testRunOTCCANSI2(self):
-        self.compileCheck(["-R", "data/otcc-ansi.c", "data/otcc.c", "data/returnval.c"],
-            "Executing compiled code:\notcc-ansi.c: About to execute compiled code:\notcc.c: about to execute compiled code.\natcc-ansi.c: result: 42\nresult: 42\n", "",['x86'])
+        global gRunOTCCOutput
+        if gRunOTCCOutput:
+            self.compileCheck(["-R", "data/otcc-ansi.c", "data/otcc.c", "data/returnval.c"],
+                "Executing compiled code:\notcc-ansi.c: About to execute compiled code:\notcc.c: about to execute compiled code.\natcc-ansi.c: result: 42\nresult: 42\n", "",['x86'])
 
     def testRunConstants(self):
         self.compileCheck(["-R", "data/constants.c"],
@@ -409,8 +438,22 @@
 result: 0
 ""","""""")
 
-if __name__ == '__main__':
+    def testDefines(self):
+        self.compileCheck(["-R", "data/defines.c"], """Executing compiled code:
+result: 3
+""","""""")
+
+    def testFuncArgs(self):
+        self.compileCheck(["-R", "data/funcargs.c"], """Executing compiled code:
+result: 4
+""","""""")
+
+def main():
+    parseArgv()
     if not outputCanRun():
-        print "Many tests are expected to fail, because acc is not a 32-bit x86 Linux executable."
+        print "Can't run output of acc compiler."
     unittest.main()
 
+if __name__ == '__main__':
+    main()
+
diff --git a/liblog/logd_write.c b/liblog/logd_write.c
index 96da38b..241dbf0 100644
--- a/liblog/logd_write.c
+++ b/liblog/logd_write.c
@@ -142,11 +142,7 @@
 
     /* XXX: This needs to go! */
     if (!strcmp(tag, "HTC_RIL") ||
-        !strcmp(tag, "RILJ") ||
-        !strcmp(tag, "RILB") ||
-        !strcmp(tag, "RILC") ||
-        !strcmp(tag, "RILD") ||
-        !strcmp(tag, "RIL") ||
+        !strncmp(tag, "RIL", 3) || /* Any log tag with "RIL" as the prefix */
         !strcmp(tag, "AT") ||
         !strcmp(tag, "GSM") ||
         !strcmp(tag, "STK") ||
diff --git a/libpixelflinger/t32cb16blend.S b/libpixelflinger/t32cb16blend.S
index d4b2579..caf9eb7 100644
--- a/libpixelflinger/t32cb16blend.S
+++ b/libpixelflinger/t32cb16blend.S
@@ -21,53 +21,80 @@
 	
 	.global scanline_t32cb16blend_arm
 
-// uses r6, r7, lr
 
-.macro pixel,   DREG, SRC, FB, OFFSET
+/*
+ * .macro pixel
+ *
+ * \DREG is a 32-bit register containing *two* original destination RGB565 
+ *       pixels, with the even one in the low-16 bits, and the odd one in the
+ *       high 16 bits.
+ *
+ * \SRC is a 32-bit 0xAABBGGRR pixel value, with pre-multiplied colors.
+ *
+ * \FB is a target register that will contain the blended pixel values.
+ *
+ * \ODD is either 0 or 1 and indicates if we're blending the lower or 
+ *      upper 16-bit pixels in DREG into FB
+ *
+ *
+ * clobbered: r6, r7, lr
+ *
+ */
 
-    // SRC = AARRGGBB
+.macro pixel,   DREG, SRC, FB, ODD
+
+    // SRC = 0xAABBGGRR
     mov     r7, \SRC, lsr #24           // sA
     add     r7, r7, r7, lsr #7          // sA + (sA >> 7)
     rsb     r7, r7, #0x100              // sA = 0x100 - (sA+(sA>>7))
 
 1:
 
-.if \OFFSET
+.if \ODD
 
     // red
-    mov     lr, \DREG, lsr #(\OFFSET + 6 + 5)
+    mov     lr, \DREG, lsr #(16 + 11)
     smulbb  lr, r7, lr
     mov     r6, \SRC, lsr #3
     and     r6, r6, #0x1F
     add     lr, r6, lr, lsr #8
-    orr     \FB, lr, lsl #(\OFFSET + 11)
+    cmp     lr, #0x1F
+    orrhs   \FB, \FB, #(0x1F<<(16 + 11))
+    orrlo   \FB, \FB, lr, lsl #(16 + 11)
 
         // green
-        and     r6, \DREG, #(0x3F<<(\OFFSET + 5))
+        and     r6, \DREG, #(0x3F<<(16 + 5))
         smulbt  r6, r7, r6
         mov     lr, \SRC, lsr #(8+2)
         and     lr, lr, #0x3F
         add     r6, lr, r6, lsr #(5+8)
-        orr     \FB, \FB, r6, lsl #(\OFFSET + 5)
+        cmp     r6, #0x3F
+        orrhs   \FB, \FB, #(0x3F<<(16 + 5))
+        orrlo   \FB, \FB, r6, lsl #(16 + 5)
 
             // blue
-            and     lr, \DREG, #(0x1F << \OFFSET)
+            and     lr, \DREG, #(0x1F << 16)
             smulbt  lr, r7, lr
             mov     r6, \SRC, lsr #(8+8+3)
             and     r6, r6, #0x1F
             add     lr, r6, lr, lsr #8
-            orr     \FB, \FB, lr, lsl #\OFFSET
+            cmp     lr, #0x1F
+            orrhs   \FB, \FB, #(0x1F << 16)
+            orrlo   \FB, \FB, lr, lsl #16
 
 .else
 
     // red
-    mov     lr, \DREG, lsr #(6+5)
+    mov     lr, \DREG, lsr #11
     and     lr, lr, #0x1F
     smulbb  lr, r7, lr
     mov     r6, \SRC, lsr #3
     and     r6, r6, #0x1F
     add     lr, r6, lr, lsr #8
-    mov     \FB, lr, lsl #11
+    cmp     lr, #0x1F
+    movhs   \FB, #(0x1F<<11)
+    movlo   \FB, lr, lsl #11
+
 
         // green
         and     r6, \DREG, #(0x3F<<5)
@@ -75,7 +102,9 @@
         mov     lr, \SRC, lsr #(8+2)
         and     lr, lr, #0x3F
         add     r6, lr, r6, lsr #(5+8)
-        orr     \FB, \FB, r6, lsl #5
+        cmp     r6, #0x3F
+        orrhs   \FB, \FB, #(0x3F<<5)
+        orrlo   \FB, \FB, r6, lsl #5
 
             // blue
             and     lr, \DREG, #0x1F
@@ -83,7 +112,9 @@
             mov     r6, \SRC, lsr #(8+8+3)
             and     r6, r6, #0x1F
             add     lr, r6, lr, lsr #8
-            orr     \FB, \FB, lr
+            cmp     lr, #0x1F
+            orrhs   \FB, \FB, #0x1F
+            orrlo   \FB, \FB, lr
 
 .endif
 
@@ -128,7 +159,7 @@
     subs    r2, r2, #2
     blo     9f
 
-    // The main loop is unrolled twice and process 4 pixels
+    // The main loop is unrolled twice and processes 4 pixels
 8:  ldmia   r1!, {r4, r5}
     // stream the source
     pld     [r1, #32]
@@ -142,7 +173,7 @@
     // stream the destination
     pld     [r0, #32]
     pixel   r3, r4, r12, 0
-    pixel   r3, r5, r12, 16
+    pixel   r3, r5, r12, 1
     // effectively, we're getting write-combining by virtue of the
     // cpu's write-back cache.
     str     r12, [r0, #-4]