+ # GCC may have put the function's epilogue code in the _middle_
+ # of the function. We try to detect that here and extract the
+ # code that belongs to the body of the function. We'll put that
+ # code back after cleaning up the epilogue.
+ # The epilogue is first split into:
+ # $e, the epilogue code (up to the return instruction)
+ # $rtail, the rest of the function body
+ # $edir, the directives following the function
+ # (everything starting with .endp)
+ # The return instruction and endp directive are stripped in the
+ # process.
+ if (!(($e, $rtail) = split(/^\tbr\.ret\.sptk\.many b0\n/, $e))) {
+ die "Epilogue doesn't seem to have one return instruction: $e\n";
+ }
+ if (!(($rtail, $edir) = split(/^\t\.endp [a-zA-Z0-9_#.]+\n/, $rtail))) {
+ die "Epilogue doesn't seem to have one endp directive: $e\n";
+ }
+ # print STDERR "Epilogue: $e\n";
+ # print STDERR "Code tail: $rtail\n";
+ # print STDERR "Directives: $edir\n";
+
+ # If a return value is saved here, move it to the function body
+ if ($e =~ /^\tmov r8 = r14\n/) {
+ $e = $` . $';
+ $r = $r . $&;
+ }
+
+ # Remove floating-point fill instructions. This is actually a bad
+ # thing to remove, because we will be putting junk into the
+ # floating-point registers and this will be visible to the caller.
+ # Only fp registers 2-5 and 16-31 may be restored.
+ if ($e =~ s/^\tldf\.fill f([2-5]|1[6-9]|2[0-9]|30|31) = \[r1[4-9]\](, [0-9]+)?\n//g) {
+ # Being paranoid, only try to remove this if we saw a fill
+ # operation.
+ $e =~ s/^\tadds r1[4-9] = [0-9]+, r12//g;
+ }
+
+ $e =~ s/^\tnop\.[mifb]\s+0\n//g; # remove nop instructions
+