I have created this monster:
I believe it is logically correct, but there must be a better way (other than assembly-language) to process the carries.
The target is the ARM.
Any ideas?
Thanks, Dave A.
--------
P.S.--The .PDF above may be easiest to read, but just in case, here is the code as text:
//---------------------------------------------------------------------------------------------------- //DESCRIPTION // Adds two signed 128-bit integers to produce a signed 128-bit result. No limiting or "railing" // is implemented, and overflow will occur as it would with native arithmetic. // //INPUTS // *in_term_to_add, *out_result: // Integers to add. These pointers may be identical or point to overlapping areas of memory. // //OUTPUTS // *out_result // The sum of *out_result and *in_term_to_add. // // uw[0] + in_term_to_add->uw[0]; //For statement coverage, Statement //Group 1
//Perform the [1] addition, possibly including carry from the [0] addition. if ( (local_temp.uw[0] < out_result->uw[0]) //For MCDC testing, Clause 1 || (local_temp.uw[0] < in_term_to_add->uw[0]) //For MCDC testing, Clause 2 ) { carry_out_of_0 = TRUE; local_temp.uw[1] = out_result->uw[1] + in_term_to_add->uw[1] +
1; //Add with carry. //For statement coverage, Statement //Group 3 } else { carry_out_of_0 = FALSE; local_temp.uw[1] = out_result->uw[1] + in_term_to_add->uw[1]; //Add without carry. //For statement coverage, Statement //Group 4 }//Perform the [2] addition, possibly including carry from the [1] addition. if ( ( (! carry_out_of_0) //For MCDC testing, Clause 3 && ( (local_temp.uw[1] < out_result->uw[1]) //For MCDC testing, Clause 4 || (local_temp.uw[1] < in_term_to_add->uw[1]) //For MCDC testing, Clause 5 ) ) || ( (carry_out_of_0) //For MCDC testing, Clause 6 && ( (local_temp.uw[1] uw[1]) //For MCDC testing, Clause 7 || (local_temp.uw[1] uw[1]) //For MCDC testing, Clause 8 ) ) ) { carry_out_of_1 = TRUE; local_temp.uw[2] = out_result->uw[2] + in_term_to_add->uw[2] +
1; //Add with carry. //For statement coverage, Statement //Group 5 } else { carry_out_of_1 = FALSE; local_temp.uw[2] = out_result->uw[2] + in_term_to_add->uw[2]; //Add without carry. //For statement coverage, Statement //Group 6 }//Perform the [3] addition, possibly including carry from the [2] addition. if ( ( (! carry_out_of_1) //For MCDC testing, Clause 9 && ( (local_temp.uw[2] < out_result->uw[2]) //For MCDC testing, Clause 10 || (local_temp.uw[2] < in_term_to_add->uw[2]) //For MCDC testing, Clause 11 ) ) || ( (carry_out_of_1) //For MCDC testing, Clause 12 && ( (local_temp.uw[2] uw[2]) //For MCDC testing, Clause 13 || (local_temp.uw[2] uw[2]) //For MCDC testing, Clause 14 ) ) ) { carry_out_of_2 = TRUE; local_temp.uw[3] = out_result->uw[3] + in_term_to_add->uw[3] +
1; //Add with carry. //For statement coverage, Statement //Group 7 } else { carry_out_of_2 = FALSE; local_temp.uw[3] = out_result->uw[3] + in_term_to_add->uw[3]; //Add without carry. //For statement coverage, Statement //Group 8 }//Decide whether a carry out of the [3] addition occurred. if ( ( (! carry_out_of_2) //For MCDC testing, Clause 15 && ( (local_temp.uw[3] < out_result->uw[3]) //For MCDC testing, Clause 16 || (local_temp.uw[3] < in_term_to_add->uw[3]) //For MCDC testing, Clause 17 ) ) || ( (carry_out_of_2) //For MCDC testing, Clause 18 && ( (local_temp.uw[3] uw[3]) //For MCDC testing, Clause 19 || (local_temp.uw[3] uw[3]) //For MCDC testing, Clause 20 ) ) ) { carry_out_of_3 = TRUE; //For statement coverage, Statement //Group 9 } else { carry_out_of_3 = FALSE; //For statement coverage, Statement //Group 10 }
//Assign the addition result back to the intended storage location. out_result->uw[3] = local_temp.uw[3]; //For statement coverage, Statement //Group 11 out_result->uw[2] = local_temp.uw[2]; out_result->uw[1] = local_temp.uw[1]; out_result->uw[0] = local_temp.uw[0];
//Return the carry information to caller. return(carry_out_of_3); }