Studying note of GCC-3.4.6 source (16)

2.3. Initialize Registers sets

Next, after init_ttree, general_init invokes init_reg_sets.

For most machines, certain registers have special usage. For example, in x86 machine, esp always holds the address of stack top, it can’t be used to pass parameter during the function call; and some other registers, according to certain convention, will be saved and restored during the function call, while the other will not. Of course, this information is machine dependent.

Here init_reg_sets just collects general information for the chip series (chips of different bits are treated same here). Later, init_reg_sets_1 will refine this information according to the architecture (chips of different bits are treated respectively).

 

261  void

262  init_reg_sets (void)                                                                                     in regclass.c

263  {

264    int i, j;

265 

266    /* First copy the register information from the initial int form into

267      the regsets.  */

268 

269    for (i = 0; i < N_REG_CLASSES; i++)

270    {

271      CLEAR_HARD_REG_SET (reg_class_contents[i]);

272 

273      /* Note that we hard-code 32 here, not HOST_BITS_PER_INT.  */

274      for (j = 0; j < FIRST_PSEUDO_REGISTER; j++)

275            if (int_reg_class_contents[i][j / 32]

276              & ((unsigned) 1 << (j % 32)))

277              SET_HARD_REG_BIT (reg_class_contents[i], j);

278    }

279 

280    memcpy (fixed_regs, initial_fixed_regs, sizeof fixed_regs);

281    memcpy (call_used_regs, initial_call_used_regs, sizeof call_used_regs);

282    memset (global_regs, 0, sizeof global_regs);

283 

284    /* Do any additional initialization regsets may need.  */

285    INIT_ONCE_REG_SET ();

286 

287  #ifdef REG_ALLOC_ORDER

288    for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)

289      inv_reg_alloc_order[reg_alloc_order[i]] = i;

290  #endif

291  }

 

As we know that some registers can be used for serval purpose, for example, in x86 machine, edx can be used to pass parameter for function call, while it also can be used to hold address for indirect memory accessment. So register should be grouped into sets for different purpose. These groupings are very important for compiler in register allocation.

Above, reg_class_contents is a global array to describe registers by the groupings. Every element contains bits enough for representing all hard registers, so it maybe a internal interge type or an array of interge according to the number of the registers. Registers are numbered, and the number is the index into bits. 1 in the bit indicates the register belongs to the group. We see that it just gets its content from int_reg_class_contents. We use it as it’s more compact.

For x86 machine, the registers numbered as following: ax (0), dx (1), cx (2), bx (3), si (4), di (5), bp (6), sp (7), st (8) ~ st7 (15), arg (16, fake register), flags (17), fpsr (18), dir (19), frame (20), xmm0 (21) ~ xmm7 (28), mmx0 (29) ~ mmx7 (36), r8 (37) ~ r15 (44), xmm8 (45) ~ xmm15 (52). As result, FIRST_PSEUDO_REGISTER is 53. The method of numbering is often recommended by ABI document.

In x86 system, st set (st0 ~ st7) are 80 bits long floating point registers. They construct a circular stack, which st7 at bottom, st1 at top. mmx set (mmx0 ~ mmx7) are 64 bits floating point registers with assoicated instructions set (57 instructions in all) to accelerate the calculation of integral floating point value. First sse set (sse0 ~ sse7) are 128 bits floating point registers with associated instructions set which is superset of that of mmx. Above sets are all available for both 32 bits & 64 bits architecture.

Second sse set (sse8 ~ sse15) are also 128 bits floating point registers with strengthened instructions set, this set is only available for 64 bits architecture. The same are r8 ~ r15, which are 64 bits general registers introduced in 64 bits architecture.

These registers are grouped into following groupings.

 

1257 /* Define the classes of registers for register constraints in the

1258   machine description. Also define ranges of constants.

1259

1260   One of the classes must always be named ALL_REGS and include all hard regs.

1261   If there is more than one class, another class must be named NO_REGS

1262   and contain no registers.

1263

1264   The name GENERAL_REGS must be the name of a class (or an alias for

1265   another name such as ALL_REGS). This is the class of registers

1266   that is allowed by "g" or "r" in a register constraint.

1267   Also, registers outside this class are allocated only when

1268   instructions express preferences for them.

1269

1270   The classes must be numbered in nondecreasing order; that is,

1271   a larger-numbered class must never be contained completely

1272   in a smaller-numbered class.

1273

1274   For any two classes, it is very desirable that there be another

1275   class that represents their union.

1276

1277   It might seem that class BREG is unnecessary, since no useful 386

1278   opcode needs reg %ebx. But some systems pass args to the OS in ebx,

1279   and the "b" register constraint is useful in asms for syscalls.

1280

1281   The flags and fpsr registers are in no class.  */

1282

1283 enum reg_class                                                                                          in i386.h

1284 {

1285   NO_REGS,

1286   AREG, DREG, CREG, BREG, SIREG, DIREG,

1287   AD_REGS,                    /* %eax/%edx for DImode */

1288   Q_REGS,                       /* %eax %ebx %ecx %edx */

1289   NON_Q_REGS,             /* %esi %edi %ebp %esp */

1290   INDEX_REGS,              /* %eax %ebx %ecx %edx %esi %edi %ebp */

1291   LEGACY_REGS,           /* %eax %ebx %ecx %edx %esi %edi %ebp %esp */

1292   GENERAL_REGS,         /* %eax %ebx %ecx %edx %esi %edi %ebp %esp %r8 - %r15*/

1293   FP_TOP_REG, FP_SECOND_REG,      /* %st(0) %st(1) */

1294   FLOAT_REGS,

1295   SSE_REGS,

1296   MMX_REGS,

1297   FP_TOP_SSE_REGS,

1298   FP_SECOND_SSE_REGS,

1299   FLOAT_SSE_REGS,

1300   FLOAT_INT_REGS,

1301   INT_SSE_REGS,

1302   FLOAT_INT_SSE_REGS,

1303   ALL_REGS, LIM_REG_CLASSES

1304 };

 

1307 #define N_REG_CLASSES ((int) LIM_REG_CLASSES)

 

CLEAR_HARD_REG_SET above at line 271 in init_reg_sets, sets reg_class_contents with 0. Line 274 ~ 278, it sets reg_class_contents same as int_reg_class_contents. The content of int_reg_class_contents is machine dependent. In x86 system, it is that in below.

 

162  #define N_REG_INTS  /

163    ((FIRST_PSEUDO_REGISTER + (32 - 1)) / 32)                                       in regclass.c

164 

165  static const unsigned int_reg_class_contents[N_REG_CLASSES][N_REG_INTS]

166    = REG_CLASS_CONTENTS;

 

1355 #define REG_CLASS_CONTENTS                                       /                    in i386.h

1356 {     { 0x00,     0x0 },                                     /

1357       { 0x01,     0x0 }, { 0x02, 0x0 }, /* AREG, DREG */              /

1358       { 0x04,     0x0 }, { 0x08, 0x0 }, /* CREG, BREG */        /

1359       { 0x10,     0x0 }, { 0x20, 0x0 }, /* SIREG, DIREG */            /

1360       { 0x03,     0x0 },        /* AD_REGS */                   /

1361       { 0x0f,     0x0 },         /* Q_REGS */                     /

1362   { 0x1100f0,  0x1fe0 },          /* NON_Q_REGS */            /

1363       { 0x7f,  0x1fe0 },          /* INDEX_REGS */             /

1364   { 0x1100ff,  0x0 },               /* LEGACY_REGS */          /

1365   { 0x1100ff,  0x1fe0 },          /* GENERAL_REGS */        /

1366      { 0x100,     0x0 }, { 0x0200, 0x0 },/* FP_TOP_REG, FP_SECOND_REG *//

1367     { 0xff00,     0x0 },         /* FLOAT_REGS */             /

1368 { 0x1fe00000,0x1fe000 },           /* SSE_REGS */                  /

1369 { 0xe0000000,    0x1f },          /* MMX_REGS */               /

1370 { 0x1fe00100,0x1fe000 },           /* FP_TOP_SSE_REG */             /

1371 { 0x1fe00200,0x1fe000 },           /* FP_SECOND_SSE_REG */            /

1372 { 0x1fe0ff00,0x1fe000 },            /* FLOAT_SSE_REGS */            /

1373    { 0x1ffff,  0x1fe0 },           /* FLOAT_INT_REGS */             /

1374 { 0x1fe100ff,0x1fffe0 },             /* INT_SSE_REGS */          /

1375 { 0x1fe1ffff,0x1fffe0 },              /* FLOAT_INT_SSE_REGS */     /

1376 { 0xffffffff,0x1fffff }                                             /

1377 }

 

Remember the register number is used as index of the bits, and here type (int [2]) needs to hold all registers (53 in all). And We can get following table according to above definition.

t6

Table 6: register classes for x86 machine

At line 280 in init_reg_sets, sets flags for register that fixed use (stack pointer, pc, frame pointer, etc.). initial_fixed_regs has below definition, in which element the first bit is used for 32 bits target, and the second bit is used for 64 bits.

 

77    static const char initial_fixed_regs[] = FIXED_REGISTERS;                         in regclass.c

 

935  /* 1 for registers that have pervasive standard uses

936    and are not available for the register allocator.

937    On the 80386, the stack pointer is such, as is the arg pointer.

938 

939    The value is a mask - bit 1 is set for fixed registers

940    for 32bit target, while 2 is set for fixed registers for 64bit.

941    Proper value is computed in the CONDITIONAL_REGISTER_USAGE.

942  */

943  #define FIXED_REGISTERS                                          /

944  /*ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7*/ /

945  { 0, 0,  0, 0, 0, 0, 0,  3, 0, 0,  0, 0,  0, 0,  0, 0,   /

946  /*arg,flags,fpsr,dir,frame*/                                /

947    3,  3,   3,  3,  3,                              /

948  /*xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7*/                     /

949     0,    0,    0,    0,    0,    0,    0,    0,               /

950  /*mmx0,mmx1,mmx2,mmx3,mmx4,mmx5,mmx6,mmx7*/                     /

951     0,    0,    0,    0,    0,    0,    0,    0,               /

952  /*  r8,  r9, r10, r11, r12, r13, r14, r15*/                 /

953     1,    1, 1,   1,  1,  1,  1,   1,                     /

954  /*xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15*/          /

955     1,    1,     1,     1,     1,     1,     1,     1}

935          

 

And at line 281 in init_reg_sets, gets flags for registers that are fixed use or are clobbered by function calls. These are the registers that cannot be used to allocate a pseudo reg whose life crosses calls unless we are able to save/restore them across the calls. They are indicated by 1 in the bits.

 

96    static const char initial_call_used_regs[] = CALL_USED_REGISTERS;          in regclass.c

 

958  /* 1 for registers not available across function calls.

959    These must include the FIXED_REGISTERS and also any

960    registers that can be used without being saved.

961    The latter must include the registers where values are returned

962    and the register where structure-value addresses are passed.

963    Aside from that, you can include as many other registers as you like.

964 

965    The value is a mask - bit 1 is set for call used

966    for 32bit target, while 2 is set for call used for 64bit.

967    Proper value is computed in the CONDITIONAL_REGISTER_USAGE.

968  */

969  #define CALL_USED_REGISTERS                                /                           in i386.h

970  /*ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7*/ /

971  { 3, 3,  3, 0, 2, 2, 0,  3, 3, 3, 3,  3,  3, 3,  3,  3,       /

972  /*arg,flags,fpsr,dir,frame*/                                /

973    3,  3,   3,  3,  3,                              /

974  /*xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7*/                     /

975     3,    3,    3,     3,    3,   3,     3,    3,                    /

976  /*mmx0,mmx1,mmx2,mmx3,mmx4,mmx5,mmx6,mmx7*/                     /

977     3,    3,    3,     3,    3,   3,     3,    3,                    /

978  /*  r8,  r9, r10, r11, r12, r13, r14, r15*/                 /

979      3,   3,  3,  3,  1,  1,  1,  1,               /

980  /*xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15*/          /

981     3,    3,     3,     3,     3,     3,     3,     3}           /

 

With above arrays, we can get following table.

t7

 

Table 7: fix & call used register groups for x86 machine

At line 285 in init_reg_sets, INIT_ONCE_REG_SETis empty macro in current version. At line 287, REG_ALLOC_ORDER if defined, indicates the order of allocation of the registers. For x86, in file i386.h, the macro is defined as an in order array of 0 ~ 52. And reg_alloc_order is initialized by REG_ALLOC_ORDER. Thus for x86, inv_reg_alloc_order is also an in order array of 0 ~ 52.

 

for Policy and Practice, 2018, 17(2): 179-195. In this article, Victor Wang Chen Neo examines the implementation of school-based curriculum development (SBCD) in Singapore. SBCD is a process where schools are given greater autonomy to develop and implement their own curriculum, rather than following a standardized national curriculum. The author begins by providing an overview of the history of curriculum development in Singapore, and how the shift towards SBCD came about. He then presents the findings of a study that he conducted, which involved interviews with school leaders who had implemented SBCD in their schools. The author identifies several factors that influenced the successful implementation of SBCD in these schools. These include strong leadership, a clear vision and direction for the school, and a focus on student learning and development. The author also highlights the importance of teacher training and support, as well as collaboration and communication among all stakeholders involved in the curriculum development process. However, the author also notes some challenges that schools face when implementing SBCD. These include a lack of resources, such as time and funding, as well as the need to balance autonomy with accountability to ensure that the curriculum developed meets national standards. Overall, the author suggests that SBCD has the potential to improve the quality of education in Singapore by allowing schools to tailor their curriculum to the needs and interests of their students. However, he also calls for continued support and guidance from the government to ensure that schools are able to implement SBCD effectively.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值