@@ -297,18 +297,25 @@ private void buildCalculatingBinaryInsn(final String binaryOperation,
297
297
// on non-primitive values
298
298
if (!(secondOperand .getType () instanceof PrimType ))
299
299
throw new RuntimeException ("Invalid value type for primitibe operation" );
300
-
301
- // If the second register is not of the precise target type, we need to
302
- // cast. This can happen, because we cannot load BYTE values. We instead
303
- // load INT constants and then need to typecast.
300
+
301
+ // For some data types, there are no calculating opcodes in Dalvik. In
302
+ // this case, we need to use a bigger opcode and cast the result back.
303
+ PrimitiveType destRegType = PrimitiveType . getByName ( destinationReg . getType (). toString ());
304
304
Register secondOpReg = regAlloc .asImmediate (secondOperand , constantV );
305
305
Register orgDestReg = destinationReg ;
306
- PrimitiveType destRegType = PrimitiveType .getByName (destinationReg .getType ().toString ());
307
- if (isBiggerThan (PrimitiveType .getByName (secondOpReg .getType ().toString ()), destRegType )) {
308
- destinationReg = regAlloc .asTmpReg (secondOpReg .getType ());
306
+ if (isSmallerThan (destRegType , PrimitiveType .INT )) {
307
+ destinationReg = regAlloc .asTmpReg (IntType .v ());
309
308
}
310
- else if (isBiggerThan (PrimitiveType .getByName (firstOpReg .getType ().toString ()), destRegType )) {
311
- destinationReg = regAlloc .asTmpReg (firstOpReg .getType ());
309
+ else {
310
+ // If the second register is not of the precise target type, we need to
311
+ // cast. This can happen, because we cannot load BYTE values. We instead
312
+ // load INT constants and then need to typecast.
313
+ if (isBiggerThan (PrimitiveType .getByName (secondOpReg .getType ().toString ()), destRegType )) {
314
+ destinationReg = regAlloc .asTmpReg (secondOpReg .getType ());
315
+ }
316
+ else if (isBiggerThan (PrimitiveType .getByName (firstOpReg .getType ().toString ()), destRegType )) {
317
+ destinationReg = regAlloc .asTmpReg (firstOpReg .getType ());
318
+ }
312
319
}
313
320
314
321
// use special "/2addr"-opcodes if destination equals first op
@@ -698,6 +705,10 @@ private boolean isBiggerThan(PrimitiveType type, PrimitiveType relativeTo) {
698
705
return type .compareTo (relativeTo ) > 0 ;
699
706
}
700
707
708
+ private boolean isSmallerThan (PrimitiveType type , PrimitiveType relativeTo ) {
709
+ return type .compareTo (relativeTo ) < 0 ;
710
+ }
711
+
701
712
private Opcode getCastOpc (PrimitiveType sourceType , PrimitiveType castType ) {
702
713
Opcode opc = Opcode .valueOf (sourceType .getName ().toUpperCase () + "_TO_"
703
714
+ castType .getName ().toUpperCase ());
0 commit comments