Précédent   Forum du club des développeurs et IT Pro > Autres langages > Assembleur > Autres architectures
Autres architectures Toutes les autres architectures (PIC, MIPS, ARM, 68K, Z80...) et leurs outils
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 25/10/2012, 11h01   #1
mith06
Membre confirmé
 
Ingénieur développement matériel électronique
Inscription : juillet 2010
Messages : 142
Détails du profil
Informations professionnelles :
Activité : Ingénieur développement matériel électronique
Secteur : Industrie

Informations forums :
Inscription : juillet 2010
Messages : 142
Points : 203
Points : 203
Par défaut Compilation gcc assembleur Microblaze

Bonjour à tous.
J'ai une question concernant la compilation par gcc vers une cible Microblaze:

Concéderons deux implémentation d'une même fonction :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 
typedef struct
{   
    /**BLABLABLA autres champs*/
    volatile uint32_t   ns;
    volatile uint32_t   sec;
    volatile uint32_t   min;
    volatile uint32_t   hrs;
    /**BLABLABLA autres champs*/
}sw_timer_t;
/**
 *\fn uint64_t sw_timer_us(const sw_timer_t * pst_swtmr)
 *\return the number of microseconds elapsed since power up of the hardware
 *\note precision is pst_swtmr->period_us
 */
uint64_t sw_timer_us(const sw_timer_t * pst_swtmr)                  |   uint64_t sw_timer_us(const sw_timer_t * pst_swtmr)
{                                                                   |   {
                                                                    |       const uint32_t hrs2us   = 3600000000;
                                                                    |       const uint32_t min2us   = 60000000;
                                                                    |       const uint32_t sec2us   = 1000000;
    const uint64_t hrs_us   = pst_swtmr->hrs*3600000000;            |       const uint64_t hrs_us   = pst_swtmr->hrs*hrs2us;
    const uint64_t min_us   = pst_swtmr->min*60000000;              |       const uint64_t min_us   = pst_swtmr->min*min2us;
    const uint64_t sec_us   = pst_swtmr->sec*1000000;               |       const uint64_t sec_us   = pst_swtmr->sec*sec2us;
    const uint32_t us       = pst_swtmr->ns/1000;                   |       const uint32_t us       = pst_swtmr->ns/1000;
    return hrs_us + min_us + sec_us + us;                           |       return hrs_us + min_us + sec_us + us;
}/* end sw_timer_us*/                                               |   }/* end sw_timer_us*/
Les codes assembleurs (Microblaze 32bits en -O2) générés par gcc sont respectivement les suivant:
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
c0000ff0 <sw_timer_us>:                                             |  c0000ff0 <sw_timer_us>:
c0000ff0:	3021ffcc 	addik	r1, r1, -52                 |  c0000ff0:	3021fff4 	addik	r1, r1, -12     
c0000ff4:	f9e10000 	swi	r15, r1, 0                  |  c0000ff4:	e8c5001c 	lwi	r6, r5, 28          
c0000ff8:	fae10020 	swi	r23, r1, 32                 |  c0000ff8:	fac10004 	swi	r22, r1, 4          
c0000ffc:	fb210028 	swi	r25, r1, 40                 |  c0000ffc:	eac50018 	lwi	r22, r5, 24         
c0001000:	fb610030 	swi	r27, r1, 48                 |  c0001000:	e9050014 	lwi	r8, r5, 20          
c0001004:	fac1001c 	swi	r22, r1, 28                 |  c0001004:	e9450010 	lwi	r10, r5, 16         
c0001008:	fb010024 	swi	r24, r1, 36                 |  c0001008:	306003e8 	addik	r3, r0, 1000    
c000100c:	fb41002c 	swi	r26, r1, 44                 |  c000100c:	10e00000 	addk	r7, r0, r0      
c0001010:	e945001c 	lwi	r10, r5, 28                 |  c0001010:	49435002 	idivu	r10, r3, r10    
c0001014:	11600000 	addk	r11, r0, r0                 |  c0001014:	fae10008 	swi	r23, r1, 8          
c0001018:	eac50018 	lwi	r22, r5, 24                 |  c0001018:	11670000 	addk	r11, r7, r0     
c000101c:	10cb0000 	addk	r6, r11, r0                 |  c000101c:	b0000393 	imm	915                 
c0001020:	eb050014 	lwi	r24, r5, 20                 |  c0001020:	62d68700 	muli	r22, r22, -30976
c0001024:	eb450010 	lwi	r26, r5, 16                 |  c0001024:	12e70000 	addk	r23, r7, r0     
c0001028:	10aa0000 	addk	r5, r10, r0                 |  c0001028:	11270000 	addk	r9, r7, r0      
c000102c:	31000000 	addik	r8, r0, 0                   |  c000102c:	b000d693 	imm	-10605              
c0001030:	b000d693 	imm	-10605                      |  c0001030:	60c6a400 	muli	r6, r6, -23552  
c0001034:	30e0a400 	addik	r7, r0, -23552              |  c0001034:	b000000f 	imm	15                  
c0001038:	132b0000 	addk	r25, r11, r0                |  c0001038:	61084240 	muli	r8, r8, 16960   
c000103c:	b0000002 	imm	2                           |  c000103c:	00c6b000 	add	r6, r6, r22         
c0001040:	b9f40314 	brlid	r15, 788	// c0021354 <__muldi3>  |  c0001040:	08e7b800 	addc	r7, r7, r23          
c0001044:	12eb0000 	addk	r23, r11, r0                |  c0001044:	eac10004 	lwi	r22, r1, 4          
c0001048:	10c30000 	addk	r6, r3, r0                  |  c0001048:	eae10008 	lwi	r23, r1, 8          
c000104c:	306003e8 	addik	r3, r0, 1000                |  c000104c:	01085000 	add	r8, r8, r10         
c0001050:	4b43d002 	idivu	r26, r3, r26                |  c0001050:	09295800 	addc	r9, r9, r11     
c0001054:	13790000 	addk	r27, r25, r0                |  c0001054:	00c64000 	add	r6, r6, r8          
c0001058:	b000000f 	imm	15                          |  c0001058:	08e74800 	addc	r7, r7, r9      
c000105c:	63184240 	muli	r24, r24, 16960             |  c000105c:	10660000 	addk	r3, r6, r0      
c0001060:	10e40000 	addk	r7, r4, r0                  |  c0001060:	10870000 	addk	r4, r7, r0      
c0001064:	b0000393 	imm	915                         |  c0001064:	b60f0008 	rtsd	r15, 8          
c0001068:	62d68700 	muli	r22, r22, -30976            |  c0001068:	3021000c 	addik	r1, r1, 12      
c000106c:	e9e10000 	lwi	r15, r1, 0                  |                   
c0001070:	02d6c000 	add	r22, r22, r24               |                       
c0001074:	0af7c800 	addc	r23, r23, r25               |                           
c0001078:	eb010024 	lwi	r24, r1, 36                 |                   
c000107c:	eb210028 	lwi	r25, r1, 40                 |                   
c0001080:	00c6d000 	add	r6, r6, r26                 |                   
c0001084:	08e7d800 	addc	r7, r7, r27                 |                       
c0001088:	02d63000 	add	r22, r22, r6                |                       
c000108c:	0af73800 	addc	r23, r23, r7                |                           
c0001090:	10760000 	addk	r3, r22, r0                 |                       
c0001094:	10970000 	addk	r4, r23, r0                 |                       
c0001098:	eac1001c 	lwi	r22, r1, 28                 |                   
c000109c:	eae10020 	lwi	r23, r1, 32                 |                   
c00010a0:	eb41002c 	lwi	r26, r1, 44                 |                   
c00010a4:	eb610030 	lwi	r27, r1, 48                 |                   
c00010a8:	b60f0008 	rtsd	r15, 8                      |                   
c00010ac:	30210034 	addik	r1, r1, 52
Je ne comprends pas pourquoi le code est si différent, et surtout pourquoi l'une fait appel à <__muldi3> (multiplication de deux entier 64 bits) et l'autre non.

Quelqu'un peut-il m’éclairer SVP?
mith06 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/10/2012, 12h33   #2
Obsidian
Modérateur
 
Avatar de Obsidian
 
Homme
Chercheur d'emploi
Inscription : septembre 2007
Messages : 4 614
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 36
Localisation : France, Essonne (Île de France)

Informations professionnelles :
Activité : Chercheur d'emploi
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : septembre 2007
Messages : 4 614
Points : 11 072
Points : 11 072
Bonjour,

Ces deux blocs ne sont pas si différents. Si tu y regardes bien, tu t'apercevras qu'il s'agit essentiellement du même code avec un certain nombre de lignes supplémentaires insérées à différents endroits. Voici par exemple les dernières lignes de l'extrait que tu as posté :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
c0001070:       02d6c000        add     r22, r22, r24                                        |c000103c:       00c6b000        add     r6, r6, r22                                         
c0001074:       0af7c800        addc    r23, r23, r25                                        |c0001040:       08e7b800        addc    r7, r7, r23
c0001078:       eb010024        lwi     r24, r1, 36                                          |c0001044:       eac10004        lwi     r22, r1, 4                                          
c000107c:       eb210028        lwi     r25, r1, 40                                          |c0001048:       eae10008        lwi     r23, r1, 8                                          
c0001080:       00c6d000        add     r6, r6, r26                                          |c000104c:       01085000        add     r8, r8, r10                                         
c0001084:       08e7d800        addc    r7, r7, r27                                          |c0001050:       09295800        addc    r9, r9, r11                                         
c0001088:       02d63000        add     r22, r22, r6                                         |c0001054:       00c64000        add     r6, r6, r8                                          
c000108c:       0af73800        addc    r23, r23, r7                                         |c0001058:       08e74800        addc    r7, r7, r9                                          
c0001090:       10760000        addk    r3, r22, r0                                          |c000105c:       10660000        addk    r3, r6, r0                                          
c0001094:       10970000        addk    r4, r23, r0                                          |c0001060:       10870000        addk    r4, r7, r0                                          
                                                                                             |                                                                                            
c0001098:       eac1001c        lwi     r22, r1, 28                                          |                                                                                            
c000109c:       eae10020        lwi     r23, r1, 32                                          |                                                                                            
c00010a0:       eb41002c        lwi     r26, r1, 44                                          |                                                                                            
c00010a4:       eb610030        lwi     r27, r1, 48                                          |                                                                                            
                                                                                             |                                                                                            
c00010a8:       b60f0008        rtsd    r15, 8                                               |c0001064:       b60f0008        rtsd    r15, 8                                              
c00010ac:       30210034        addik   r1, r1, 52                                           |c0001068:       3021000c        addik   r1, r1, 12
Ensuite, lorsqu'en C, tu déclares une variable comme étant constante (avec const), ce qui est effectivement un oxymore, tu indiques que sa valeur ne peut pas être modifiée, certes, mais il n'en reste pas moins qu'elle existe en mémoire et que, entre autres, on doit pouvoir retrouver son adresse avec « & ». Et la norme rend les choses encore plus ambiguës parce qu'elle désigne quand même par le terme « constante » les valeurs spécifiées littéralement dans le code.

Ces deux codes ne sont donc pas équivalents. L'un des deux doit entre autres déposer les valeurs initiales dans la pile ou ce qui en tient lieu sur l'architecture que tu utilises. C'est important lorsque l'on utilise des threads ou, en embarqué et bas-niveau, lorsque du matériel peut également accéder à la mémoire via DMA (par exemple une carte son ou vidéo).

Après, le compilateur peut — ou non — effectuer certaines optimisations en fonction des options que tu lui passes. Vois du côté de « -O » si tu ne l'as pas déjà fait.

Pour <multid3>, on ne sait pas à quoi sert cette fonction et on ne voit pas son code non plus, mais il est probable qu'il s'agisse d'une routine qui fasse une multiplication qui soit à la fois large (« 3600000000 » ne tient pas sur 32 bits signés) et utilisant une opérande en mémoire plutôt que dans un des registres du processeur.
Obsidian est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/10/2012, 11h28   #3
mith06
Membre confirmé
 
Ingénieur développement matériel électronique
Inscription : juillet 2010
Messages : 142
Détails du profil
Informations professionnelles :
Activité : Ingénieur développement matériel électronique
Secteur : Industrie

Informations forums :
Inscription : juillet 2010
Messages : 142
Points : 203
Points : 203
Merci pour ta réponse.

Pour info <multid3> est un fonction de la libgcc qui renvoie un entier signé sur 64 bits étant le résultat de la multiplication de 2 non signé sur 32 bits :
http://lxr.free-electrons.com/source...b/muldi3.c#L50

Les voies de gcc sont impénétrables...
mith06 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 23h41.


 
 
 
 
Partenaires

Hébergement Web