Reputation: 311
Is there a way with a recent gcc to disable the use of coprocessor instructions: CDP, LDC, STC, MCR and MRC ?
They seem to be grouped in an autoconf variable named arm_coproc1_ok.
I tried to set the options -march=armv4 and -mfloat-abi=soft but nothing helps. My binaries always contain the instructions.
Whether it's my source code or libc (newlib), I find copro instructions.
This c++ code source,
double Bbp::S(int j)
{
double s = 0.0; // Summation of Total, Left
double t; // Each term of right summation
int r; // Denominator
int k; // Loop index
double EPS = 1.0e-17; // Loop-exit accuration of the right summation
// Left Sum (0 ... d)
for (k = 0; k <= d; k++) {
r = 8 * k + j;
t = (double)compModExp(16, d - k, r);
t /= r;
s += t - (int)t;
s -= (int)s;
}
// Right sum (d + 1 ...)
while (1) {
r = 8 * k + j;
t = std::pow(16.0, (double)(d - k));
t /= (double)r;
if (t < EPS) break;
s += t;
s -= (int)s;
k ++;
}
return s;
}
...generate this binary (stc at 0x44c):
000001c0 <_ZN3Bbp1SEi>:
1c0: e52de004 push {lr} ; (str lr, [sp, #-4]!)
1c4: e24dd034 sub sp, sp, #52 ; 0x34
1c8: e58d0004 str r0, [sp, #4]
1cc: e58d1000 str r1, [sp]
1d0: e3a02000 mov r2, #0
...
440: e49df004 pop {pc} ; (ldr pc, [sp], #4)
444: e1a00000 nop ; (mov r0, r0)
448: 4646d497 ; <UNDEFINED> instruction: 0x4646d497
44c: 3c670ef5 stclcc 14, cr0, [r7], #-980 ; 0xfffffc2c
Same remark with libc.a of newlib at 0x080 (mrc instruction):
00000028 <etens>:
28: 4a926576 bmi fe499608 <enan+0xfe49565c>
2c: 153f804a ldrne r8, [pc, #-74]! ; ffffffea <enan+0xffffc03e>
30: 979ac94c ldrls ip, [sl, ip, asr #18]
...
5c: 75868175 strvc r8, [r6, #373] ; 0x175
60: 4d48c976 vstrmi.16 s25, [r8, #-236] ; 0xffffff14 ; <UNPREDICTABLE>
64: 58f89c66 ldmpl r8!, {r1, r2, r5, r6, sl, fp, ip, pc}^
68: 5c54bc50 mrrcpl 12, 5, fp, r4, cr0
6c: 91c6cc65 bicls ip, r6, r5, ror #24
70: a0aea60e adcge sl, lr, lr, lsl #12
74: 46a3e319 ssatmi lr, #4, r9, lsl #6
78: eab7851e b fede14f8 <enan+0xfeddd54c>
7c: 901b98fe ; <UNDEFINED> instruction: 0x901b98fe
80: de8dddbb mcrle 13, 4, sp, cr13, cr11, {5}
...among others obviouly.
Thank you.
Upvotes: 2
Views: 536
Reputation: 71526
double fun ( void )
{
double EPS = 1.0e-17;
return(EPS);
}
00000000 <fun>:
0: e28f1008 add r1, pc, #8
4: e8910003 ldm r1, {r0, r1}
8: e1a0f00e mov pc, lr
c: e1a00000 nop ; (mov r0, r0)
10: 4646d497 ; <UNDEFINED> instruction: 0x4646d497
14: 3c670ef5 stclcc 14, cr0, [r7], #-980 ; 0xfffffc2c
of which
code:
00000000 <fun>:
0: e28f1008 add r1, pc, #8
4: e8910003 ldm r1, {r0, r1}
8: e1a0f00e mov pc, lr
padding?
c: e1a00000 nop ; (mov r0, r0)
data pool:
10: 4646d497 ; <UNDEFINED> instruction: 0x4646d497
14: 3c670ef5 stclcc 14, cr0, [r7], #-980 ; 0xfffffc2c
and here you go
double fun ( void )
{
double EPS = 1.0e-16;
return(EPS);
}
00000000 <fun>:
0: e28f1008 add r1, pc, #8
4: e8910003 ldm r1, {r0, r1}
8: e1a0f00e mov pc, lr
c: e1a00000 nop ; (mov r0, r0)
10: 97d889bc ; <UNDEFINED> instruction: 0x97d889bc
14: 3c9cd2b2 lfmcc f5, 1, [r12], {178} ; 0xb2
the correct way to view the disassembled information is:
00000000 <fun>:
0: e28f1008 add r1, pc, #8
4: e8910003 ldm r1, {r0, r1}
8: e1a0f00e mov pc, lr
c: e1a00000
10: 4646d497
14: 3c670ef5
another way to look at this is to compile to asm
.arch armv4
.eabi_attribute 20, 1
.eabi_attribute 21, 1
.eabi_attribute 23, 3
.eabi_attribute 24, 1
.eabi_attribute 25, 1
.eabi_attribute 26, 1
.eabi_attribute 30, 2
.eabi_attribute 34, 0
.eabi_attribute 18, 4
.file "so.c"
.text
.align 2
.global fun
.syntax unified
.arm
.fpu softvfp
.type fun, %function
fun:
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 0, uses_anonymous_args = 0
@ link register save eliminated.
adr r1, .L3
ldmia r1, {r0-r1}
mov pc, lr
.L4:
.align 3
.L3:
.word 1179047063
.word 1013386997
.size fun, .-fun
.ident "GCC: (GNU) 9.2.0"
notice the lack of an stc instructions? If you convert those .words to hex you will see the pattern that a disassembler would recognize as an stc if it didnt know this was data.
And we can see where the nop came from.
Upvotes: 1
Reputation: 2491
You’re reading the literal pool (data) as code. Those “instructions” will never execute.
Try turning your
double EPS = 1.0e-17; // Loop-exit accuration of the right summation
Constant in to hexadecimal, and you’ll see why no amount of GCC options will eliminate this from your generated binary!
Upvotes: 0