Forum: Mikrocontroller und Digitale Elektronik [ARM7, IAR] Codeerzeugung unsigned short -> short


von Matthias Larisch (Gast)


Lesenswert?

Hallo zusammen,

Ich versuche gerade, eine Eigenheit vom IAR Compiler (benutze KickStart 
5.20) bei der Codeerzeugung für ARM7TDMI / Thumb Code zu verstehen:

Das Konstrukt sieht in etwa so aus:
1
volatile unsigned short *databus;
2
3
signed short meineFunktion()
4
{
5
  signed short result;
6
  read_enable();
7
  result = *databus;
8
  read_disable();
9
  return result;
10
}
11
void meineZweiteFunktion(signed short *data)
12
{
13
  for i=0..4
14
  {
15
    *data[i] = meineFunktion();
16
  }
17
}

Der IAR erzeugt folgenden Assemblercode:
1
  RD_R;
2
  000028BA  0401      LSL          R1, R0, #16
3
  000028BC  60B9      STR          R1, [R7, #8]
4
  result = (INT16S)*Databus;
5
  000028BE  4A12      LDR          R2, [PC,#0x048]          ; [??DataTable1 (0x2908)] =Databus (0x40000898)
6
  000028C0  6812      LDR          R2, [R2, #0]
7
  000028C2  8813      LDRH         R3, [R2, #0]
8
  000028C4  041B      LSL          R3, R3, #16
9
  000028C6  141B      ASR          R3, R3, #16
10
  RD_N;
11
  000028C8  6079      STR          R1, [R7, #4]
12
  000028CA  8023      STRH         R3, [R4, #0]
13
  RD_R;
14
  000028CC  60B9      STR          R1, [R7, #8]
15
  result = (INT16S)*Databus;
16
  000028CE  8813      LDRH         R3, [R2, #0]
17
  000028D0  041B      LSL          R3, R3, #16
18
  000028D2  141B      ASR          R3, R3, #16
19
  RD_N;
20
  000028D4  6079      STR          R1, [R7, #4]
21
  000028D6  8063      STRH         R3, [R4, #2]
22
  RD_R;
23
  000028D8  60B9      STR          R1, [R7, #8]
24
  result = (INT16S)*Databus;
25
  000028DA  8813      LDRH         R3, [R2, #0]
26
  000028DC  041B      LSL          R3, R3, #16
27
  000028DE  141B      ASR          R3, R3, #16
28
  RD_N;
29
  000028E0  6079      STR          R1, [R7, #4]
30
  000028E2  80A3      STRH         R3, [R4, #4]
31
  RD_R;
32
  000028E4  60B9      STR          R1, [R7, #8]

(Ausschnitt; R1 ist der Wert für read enable/disable im Fast IO 
Set/Clear Register)

Ich vermute, dass die LSL/ASR Orgien mit 16 Bit eine Sign Extension 
erwirken sollen, welche durch den Half-Word Store gleich wieder 
verworfen wird. Achso, der explizite Cast auf signed short * hat keinen 
Einfluss auf die Erzeugung der LSL/ASR Befehle, den hatte ich eben nur 
mal zum Testen reingemacht.
a) gäbe es LDRSH für die Sign extension
b) wenn er sie eh verwirft, warum macht er sie dann?

Der Code ist mit Optimierung auf High -> "speed" und jeglichen 
Optimierungen aktiviert entstanden.

Ein weiterer Punkt: Viele static void Funktionen, welche 2-3 Mal in der 
Datei vorkommen und selbst nur 2-3 Instruktionen enthalten, werden nicht 
geinlined sondern über 2 branches (bl, bx) angesprungen. Was soll das? 
Vom GCC bin ich da inlining gewöhnt und programmiere deswegen auch auf 
dem µC sehr modular - solange es nur ein Einzeiler ist, der nicht 
allzuoft verwendet wird und in der gleichen Datei vorkommt erwarte ich 
mir inlining. Zuviel verlangt?

Kommentare? Hab ich was falsch verstanden?

von Matthias Larisch (Gast)


Lesenswert?

Okay, den zweiten Teil habe ich mir gerade selbst beantwortet:
Es ging um Code im Interrupt. Scheinbar hält sich der compiler strikt an 
die Vorgabe, Thumbcode zu erzeugen. Der Interrupthandler selbst ist ja 
ARM Code, daher muss er mit bx nach Thumb umschalten und springt dann 
erst die Funktionen an. Gleiches verhalten übrigens bei #pragma 
inline=forced wobei es dann noch ne Warnung "could not inline function 
<name>" dazu gibt.

Blöd!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.