Studying note of GCC-3.4.6 source (43)

4.2.1.3.2.2.      Objects for real constant

Following, init_emit_once goes to initialize real constants.

 

init_emit_once (continue)

 

5546   REAL_VALUE_FROM_INT (dconst0,   0,  0, double_mode);

5547   REAL_VALUE_FROM_INT (dconst1,   1,  0, double_mode);

5548   REAL_VALUE_FROM_INT (dconst2,   2,  0, double_mode);

5549   REAL_VALUE_FROM_INT (dconst3,   3,  0, double_mode);

5550   REAL_VALUE_FROM_INT (dconst10, 10,  0, double_mode);

5551   REAL_VALUE_FROM_INT (dconstm1, -1, -1, double_mode);

5552   REAL_VALUE_FROM_INT (dconstm2, -2, -1, double_mode);

5553

5554   dconsthalf = dconst1;

5555   dconsthalf.exp--;

5556

5557   real_arithmetic (&dconstthird, RDIV_EXPR, &dconst1, &dconst3);

5558

5559   /* Initialize mathematical constants for constant folding builtins.

5560     These constants need to be given to at least 160 bits precision.  */

5561   real_from_string (&dconstpi,

5562     "3.1415926535897932384626433832795028841971693993751058209749445923078");

5563   real_from_string (&dconste,

5564     "2.7182818284590452353602874713526624977572470936999595749669676277241");

 

REAL_VALUE_FROM_INT is used to create RTX real constant objects from integer constant. dconst… are all global variables of type real_value.

 

279  #define REAL_VALUE_FROM_INT(r, lo, hi, mode) /                                         in real.h

280    real_from_integer (&(r), mode, lo, hi, 0)

 

Next in init_emit_once, at line 5554, it comes to create const float number 1/2, then 1/3 at 5557, and then π & e at line 5561 & 5563.

 

init_emit_once (continue)

 

5566   for (i = 0; i < (int) ARRAY_SIZE (const_tiny_rtx); i++)

5567   {

5568     REAL_VALUE_TYPE *r =

5569            (i == 0 ? &dconst0 : i == 1 ? &dconst1 : &dconst2);

5570

5571     for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT); mode != VOIDmode;

5572          mode = GET_MODE_WIDER_MODE (mode))

5573        const_tiny_rtx[i][(int) mode] =

5574             CONST_DOUBLE_FROM_REAL_VALUE (*r, mode);

5575

5576     const_tiny_rtx[i][(int) VOIDmode] = GEN_INT (i);

5577

5578     for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode;

5579          mode = GET_MODE_WIDER_MODE (mode))

5580        const_tiny_rtx[i][(int) mode] = GEN_INT (i);

5581

5582      for (mode = GET_CLASS_NARROWEST_MODE (MODE_PARTIAL_INT);

5583         mode != VOIDmode;

5584           mode = GET_MODE_WIDER_MODE (mode))

5585        const_tiny_rtx[i][(int) mode] = GEN_INT (i);

5586    }

5587

5588   for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT);

5589        mode != VOIDmode;

5590        mode = GET_MODE_WIDER_MODE (mode))

5591     const_tiny_rtx[0][(int) mode] = gen_const_vector_0 (mode);

5592

5593   for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT);

5594        mode != VOIDmode;

5595        mode = GET_MODE_WIDER_MODE (mode))

5596     const_tiny_rtx[0][(int) mode] = gen_const_vector_0 (mode);

5597

5598   for (i = (int) CCmode; i < (int) MAX_MACHINE_MODE; ++i)

5599     if (GET_MODE_CLASS ((enum machine_mode) i) == MODE_CC)

5600       const_tiny_rtx[0][i] = const0_rtx;

5601

5602   const_tiny_rtx[0][(int) BImode] = const0_rtx;

5603   if (STORE_FLAG_VALUE == 1)

5604     const_tiny_rtx[1][(int) BImode] = const1_rtx;

5605

5606 #ifdef RETURN_ADDRESS_POINTER_REGNUM

5607   return_address_pointer_rtx

5608     = gen_raw_REG (Pmode, RETURN_ADDRESS_POINTER_REGNUM);

5609 #endif

5610

5611 #ifdef STATIC_CHAIN_REGNUM

5612   static_chain_rtx = gen_rtx_REG (Pmode, STATIC_CHAIN_REGNUM);

5613

5614 #ifdef STATIC_CHAIN_INCOMING_REGNUM

5615   if (STATIC_CHAIN_INCOMING_REGNUM != STATIC_CHAIN_REGNUM)

5616     static_chain_incoming_rtx

5617       = gen_rtx_REG (Pmode, STATIC_CHAIN_INCOMING_REGNUM);

5618   else

5619 #endif

5620     static_chain_incoming_rtx = static_chain_rtx;

5621 #endif

5622

5623 #ifdef STATIC_CHAIN

5624   static_chain_rtx = STATIC_CHAIN;

5625

5626 #ifdef STATIC_CHAIN_INCOMING

5627   static_chain_incoming_rtx = STATIC_CHAIN_INCOMING;

5628 #else

5629   static_chain_incoming_rtx = static_chain_rtx;

5630 #endif

5631 #endif

5632

5633   if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)

5634     pic_offset_table_rtx = gen_raw_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);

5635 }

 

Also above, const_tiny_rtx is a global array with definition as: rtx const_tiny_rtx[3][(int) MAX_MACHINE_MODE]. It records all possible constants of integer and floating with value 0, 1 or 2 with available mode. Makes them unique and globally accessing.

At line 5574, CONST_DOUBLE_FROM_REAL_VALUE is used to create rtx objects with value of 0.0, 1.0 and 2.0.

 

350    #define CONST_DOUBLE_FROM_REAL_VALUE(r, m) /                                 in real.h

351      const_double_from_real_value (r, m)

 

436    rtx

437    const_double_from_real_value (REAL_VALUE_TYPE value, enum machine_mode mode)

438    {

439      rtx real = rtx_alloc (CONST_DOUBLE);

440      PUT_MODE (real, mode);

441   

442      memcpy (&CONST_DOUBLE_LOW (real), &value, sizeof (REAL_VALUE_TYPE));

443   

444      return lookup_const_double (real);

445    }

 

Following macros are used to handle float value in rtx object. In below the macro XCWINT fetches hwint field of rtunion in the rtx object.

 

1050 #define CONST_DOUBLE_LOW(r) XCWINT (r, 0, CONST_DOUBLE)                     in rtl.h

1051 #define CONST_DOUBLE_HIGH(r) XCWINT (r, 1, CONST_DOUBLE)

1052 #define CONST_DOUBLE_REAL_VALUE(r) ((struct real_value *)&CONST_DOUBLE_LOW(r))

 

At line 444 in const_double_from_real_value, lookup_const_double checks the hash table const_double_htab if the object created already or not. If find, returns the already existing object, otherwise, returns the object created in the function and insert it into the hash table.

GEN_INT is the function to create constant integer rtx object.

 

1882 #define GEN_INT(N)  gen_rtx_CONST_INT (VOIDmode, (HOST_WIDE_INT) (N)) in rtl.h

 

389    rtx

390    gen_rtx_CONST_INT (enum machine_mode mode ATTRIBUTE_UNUSED, HOST_WIDE_INT arg)

391    {

392      void **slot;

393   

394      if (arg >= - MAX_SAVED_CONST_INT && arg <= MAX_SAVED_CONST_INT)

395        return const_int_rtx[arg + MAX_SAVED_CONST_INT];

396   

397    #if STORE_FLAG_VALUE != 1 && STORE_FLAG_VALUE != -1

398      if (const_true_rtx && arg == STORE_FLAG_VALUE)

399        return const_true_rtx;

400    #endif

401   

402     /* Look up the CONST_INT in the hash table.  */

403      slot = htab_find_slot_with_hash (const_int_htab, &arg,

404                                 (hashval_t) arg, INSERT);

405      if (*slot == 0)

406        *slot = gen_rtx_raw_CONST_INT (VOIDmode, arg);

407   

408      return (rtx) *slot;

409    }

 

At line 5591 and 5596 in init_emit_once, gen_const_vector_0 creates constant of 0 for vector modes, which is also cached by const_tiny_rtx.

 

5402 static rtx

5403 gen_const_vector_0 (enum machine_mode mode)                                         in emit-rtl.c

5404 {

5405   rtx tem;

5406   rtvec v;

5407   int units, i;

5408   enum machine_mode inner;

5409

5410   units = GET_MODE_NUNITS (mode);

5411   inner = GET_MODE_INNER (mode);

5412

5413   v = rtvec_alloc (units);

5414

5415   /* We need to call this function after we to set CONST0_RTX first.  */

5416   if (!CONST0_RTX (inner))

5417     abort ();

5418

5419   for (i = 0; i < units; ++i)

5420     RTVEC_ELT (v, i) = CONST0_RTX (inner);

5421

5422   tem = gen_rtx_raw_CONST_VECTOR (mode, v);

5423   return tem;

5424 }

 

At line 5410 and 5411, macros GET_MODE_NUNITS and GET_MODE_INNER selects specified element of mode_nunits and mode_inner, which both are global arrays and created by genmodes tool into file insn-modes.c. mode_nunits defines the size of the vector. mode_inner then defines the mode of element in the vector.

At line 5406, type rtvec is defined as pointer to rtvec_def structure. Rtvec_def is one of fields of rtunion.

 

261    struct rtvec_def GTY(()) {                                                                               in rtl.h

262      int num_elem;         /* number of elements */

263      rtx GTY ((length ("%h.num_elem"))) elem[1];

264    };

 

RTVEC_ELT at line 5420 is a macro to access the specified item of rtvec.

 

343    #define RTVEC_ELT(RTVEC, I) __extension__                           /                    in rtl.h

344    (*({ rtvec const _rtvec = (RTVEC); const int _i = (I);                  /

345         if (_i < 0 || _i >= GET_NUM_ELEM (_rtvec))                           /

346           rtvec_check_failed_bounds (_rtvec, _i, __FILE__, __LINE__,  /

347                                __FUNCTION__);                   /

348         &_rtvec->elem[_i]; }))

 

Above at line 5416, macro CONST0_RTX selects specified mode of const_tiny_rtx is created just before.

 

1789 #define CONST0_RTX(MODE) (const_tiny_rtx[0][(int) (MODE)])                       in rtl.h

 

At line 5422, gen_rtx_raw_CONST_VECTOR is defined as:

 

235  #define gen_rtx_raw_CONST_VECTOR(MODE, ARG0) /                             in genrtl.h

236      gen_rtx_fmt_E (CONST_VECTOR, (MODE), (ARG0))

 

gen_rtx_fmt_E is also generated by gengenrtl tool, and is put into genrtl.c. From its name, we know that it creates rtx object has only one child of type rtvec.

In the rest of init_emit_once, at line 5603, STORE_FLAG_VALUE is 1 for x86 system; at line 5606, RETURN_ADDRESS_POINTER_REGNUM is not defined; at line 5614, 5623, and 5626 STATIC_CHAIN_INCOMING_REGNUM, STATIC_CHAIN_INCOMING, STATIC_CHAIN are also not defined in x86 system.

At line 5611, macro STATIC_CHAIN_REGNUM specifies the register number of register to pass static chain to function. For 32 bits ABI (pentium alike) ecx is used. While for 64 bits ABI (IA64 alike) ecx is an argument register, r10 is used instead.

In languages which allow nested lexical scoping, a pointer to the ActivationRecord (a data structure containing the important state information for a particular instance of a function call or something that resembles a function call) of the enclosing scope - this pointer is called the static chain. In most such languages, it is generally a requirement that somewhere up the call chain, the enclosing function have been called (but in concurrent languages it may have been called in a different thread). In languages like C/C++ where nested lexical scopes are disallowed or restricted (standard C/C++ disallow nested function), a static chain is unnecessary. But GNU C++ has an extension to support nested function.

At last, init_emit_once tries to create rtx object register which holds the addressing base for position independent code access to data items. For 64 bits x86 architecture, PIC_OFFSET_TABLE_REGNUM is defined as INVALID_REGNUM – no pic_offset_table_rtx will be created. To avoid clobbering a call-saved register unnecessarily, gcc may renumber the pic register when possible. Here, at first, ebx is assigned as PIC register.

4.2.2. Initialize the register sets

Back to backend_init, for machine, registers are precious assessment. When running program, many times we need put the content of the register into the memory to make it ready for next instruction and then restore the content from memory when needed. But too many traffic between register and memory creates the bottleneck. So the allocation of register should be carefully handled. To facilitate registers allocation, registers are grouped by their possible usage and their availability under certain circumstance, then relationships between groups are collected as possible. All these are done by function init_regs.

 

561  void

562  init_regs (void)                                                                                         in regclass.c

563  {

564    /* This finishes what was started by init_reg_sets, but couldn't be done

565      until after register usage was specified.  */

566    init_reg_sets_1 ();

567 

568    init_reg_autoinc ();

569  }

 

296  static void

297  init_reg_sets_1 (void)                                                                                in regclass.c

298  {

299    unsigned int i, j;

300    unsigned int /* enum machine_mode */ m;

301    char allocatable_regs_of_mode [MAX_MACHINE_MODE];

302 

303    /* This macro allows the fixed or call-used registers

304      and the register classes to depend on target flags.  */

305 

306  #ifdef CONDITIONAL_REGISTER_USAGE

307    CONDITIONAL_REGISTER_USAGE;

308  #endif

4.2.3. Determine register sets

Recall that in init_reg_sets, we have collected register information relative to the target machine into fixed_regs, call_used_regs, reg_class_content. The information describes the capacity and availability of registers for all variants of the machine, so now it needs to finer the information according to the variant in used. This update is done in CONDITIONAL_REGISTER_USAGE.

 

1005 /* Macro to conditionally modify fixed_regs/call_used_regs.  */                   in i386.h

1006 #define CONDITIONAL_REGISTER_USAGE                              /

1007 do {                                                               /

1008     int i;                                                       /

1009     for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)                        /

1010     {                                                            /

1011       fixed_regs[i] = (fixed_regs[i] & (TARGET_64BIT ? 2 : 1)) != 0;  /

1012       call_used_regs[i] = (call_used_regs[i]                          /

1013                   & (TARGET_64BIT ? 2 : 1)) != 0;            /

1014     }                                                            /

1015     if (PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)                   /

1016     {                                                            /

1017       fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1;                    /

1018       call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1;                     /

1019     }                                                            /

1020     if (! TARGET_MMX)                                            /

1021     {                                                            /

1022       int i;                                                   /

1023       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)                     /

1024         if (TEST_HARD_REG_BIT (reg_class_contents[(int)MMX_REGS], i)) /

1025           fixed_regs[i] = call_used_regs[i] = 1;                  /

1026     }                                                            /

1027     if (! TARGET_SSE)                                              /

1028     {                                                            /

1029       int i;                                                   /

1030       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)                     /

1031         if (TEST_HARD_REG_BIT (reg_class_contents[(int)SSE_REGS], i))    /

1032           fixed_regs[i] = call_used_regs[i] = 1;                  /

1033     }                                                            /

1034     if (! TARGET_80387 && ! TARGET_FLOAT_RETURNS_IN_80387)          /

1035     {                                                            /

1036       int i;                                                   /

1037       HARD_REG_SET x;                                                 /

1038       COPY_HARD_REG_SET (x, reg_class_contents[(int)FLOAT_REGS]);     /

1039       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)                     /

1040         if (TEST_HARD_REG_BIT (x, i))                         /

1041           fixed_regs[i] = call_used_regs[i] = 1;                    /

1042     }                                                            /

1043   } while (0)

 

Above, remember that for every byte of fixed_regs, call_used_regs, not zero means that register is not available for the purpose for certain variance of the machine. First bit used for 32 bit system, second bit used for 64 bit system (see Table 6: register classes for x86 machine).

4.2.3.1.    Determine relation of subset and superset

As there is intersection between register sets, some sets are subset of others. Next it needs to find out these relations.

 

init_reg_sets_1 (continue)

 

310    /* Compute number of hard regs in each class.  */

311  

312    memset (reg_class_size, 0, sizeof reg_class_size);

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

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

315        if (TEST_HARD_REG_BIT (reg_class_contents[i], j))

316          reg_class_size[i]++;

317 

318   /* Initialize the table of subunions.

319      reg_class_subunion[I][J] gets the largest-numbered reg-class

320      that is contained in the union of classes I and J.  */

321 

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

323    {

324      for (j = 0; j < N_REG_CLASSES; j++)

325      {

326        HARD_REG_SET c;

327        int k;

328 

329        COPY_HARD_REG_SET (c, reg_class_contents[i]);

330        IOR_HARD_REG_SET (c, reg_class_contents[j]);

331        for (k = 0; k < N_REG_CLASSES; k++)

332        {

333          GO_IF_HARD_REG_SUBSET (reg_class_contents[k], c,

334                            subclass1);

335          continue;

336 

337        subclass1:

338          /* Keep the largest subclass.  */           /* SPEE 900308 */

339          GO_IF_HARD_REG_SUBSET (reg_class_contents[k],

340                            reg_class_contents[(int) reg_class_subunion[i][j]],

341                            subclass2);

342          reg_class_subunion[i][j] = (enum reg_class) k;

343        subclass2:

344          ;

345        }

346      }

347    }

348 

349   /* Initialize the table of superunions.

350      reg_class_superunion[I][J] gets the smallest-numbered reg-class

351      containing the union of classes I and J.  */

352 

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

354    {

355      for (j = 0; j < N_REG_CLASSES; j++)

356      {

357        HARD_REG_SET c;

358        int k;

359 

360        COPY_HARD_REG_SET (c, reg_class_contents[i]);

361        IOR_HARD_REG_SET (c, reg_class_contents[j]);

362        for (k = 0; k < N_REG_CLASSES; k++)

363          GO_IF_HARD_REG_SUBSET (c, reg_class_contents[k], superclass);

364 

365    superclass:

366        reg_class_superunion[i][j] = (enum reg_class) k;

367      }

368    }

369 

370    /* Initialize the tables of subclasses and superclasses of each reg class.

371      First clear the whole table, then add the elements as they are found.  */

372 

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

374    {

375      for (j = 0; j < N_REG_CLASSES; j++)

376      {

377        reg_class_superclasses[i][j] = LIM_REG_CLASSES;

378        reg_class_subclasses[i][j] = LIM_REG_CLASSES;

379      }

380    }

381 

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

383    {

384      if (i == (int) NO_REGS)

385        continue;

386 

387      for (j = i + 1; j < N_REG_CLASSES; j++)

388      {

389        enum reg_class *p;

390 

391        GO_IF_HARD_REG_SUBSET (reg_class_contents[i], reg_class_contents[j],

392                       subclass);

393        continue;

394    subclass:

395        /* Reg class I is a subclass of J.

396         Add J to the table of superclasses of I.  */

397        p = &reg_class_superclasses[i][0];

398        while (*p != LIM_REG_CLASSES) p++;

399          *p = (enum reg_class) j;

400        /* Add I to the table of superclasses of J.  */

401        p = &reg_class_subclasses[j][0];

402        while (*p != LIM_REG_CLASSES) p++;

403          *p = (enum reg_class) i;

404      }

405    }

 

Above, line 312~316 counts registers for every class and records the number into reg_class_size. Then line 322~347 finds out the register class that is the largest subset of the union of any two register classes and saves the result into reg_class_subunion, line 353~368 finds out the register class that is the smallest superset of the union of any two register classes and saves the result into reg_class_superunion. Note that in reg_class_contents 1 in the bits which indexed by register number indicates the present of corresponding register.

The action of GO_IF_HARD_REG_SUBSET (X, Y, TO) is: if X is contained by Y jump to TO. Line 373~405 then finds out which register class is contained by specified register class and vice versa (i.e. if X is contained by Y, Y is supperclass of X, and X is subclass of Y).

 

init_reg_sets_1 (continue)

 

407    /* Initialize "constant" tables.  */

408 

409    CLEAR_HARD_REG_SET (fixed_reg_set);

410    CLEAR_HARD_REG_SET (call_used_reg_set);

411     CLEAR_HARD_REG_SET (call_fixed_reg_set);

412    CLEAR_HARD_REG_SET (regs_invalidated_by_call);

413 

414    memcpy (call_fixed_regs, fixed_regs, sizeof call_fixed_regs);

415 

416    n_non_fixed_regs = 0;

417 

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

419    {

420      if (fixed_regs[i])

421        SET_HARD_REG_BIT (fixed_reg_set, i);

422      else

423        n_non_fixed_regs++;

424 

425      if (call_used_regs[i])

426        SET_HARD_REG_BIT (call_used_reg_set, i);

427      if (call_fixed_regs[i])

428        SET_HARD_REG_BIT (call_fixed_reg_set, i);

429      if (CLASS_LIKELY_SPILLED_P (REGNO_REG_CLASS (i)))

430        SET_HARD_REG_BIT (losing_caller_save_reg_set, i);

431 

432      /* There are a couple of fixed registers that we know are safe to

433        exclude from being clobbered by calls:

434 

435        The frame pointer is always preserved across calls. The arg pointer

436        is if it is fixed. The stack pointer usually is, unless

437        RETURN_POPS_ARGS, in which case an explicit CLOBBER will be present.

438        If we are generating PIC code, the PIC offset table register is

439        preserved across calls, though the target can override that.  */

440 

441      if (i == STACK_POINTER_REGNUM)

442        ;

443      else if (global_regs[i])

444        SET_HARD_REG_BIT (regs_invalidated_by_call, i);

445      else if (i == FRAME_POINTER_REGNUM)

446        ;

447  #if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM

448      else if (i == HARD_FRAME_POINTER_REGNUM)

449        ;

450  #endif

451  #if ARG_POINTER_REGNUM != FRAME_POINTER_REGNUM

452      else if (i == ARG_POINTER_REGNUM && fixed_regs[i])

453        ;

454  #endif

455  #ifndef PIC_OFFSET_TABLE_REG_CALL_CLOBBERED

456      else if (i == (unsigned) PIC_OFFSET_TABLE_REGNUM && fixed_regs[i])

457        ;

458  #endif

459      else if (CALL_REALLY_USED_REGNO_P (i))

460        SET_HARD_REG_BIT (regs_invalidated_by_call, i);

461    }

462 

463    memset (contains_reg_of_mode, 0, sizeof (contains_reg_of_mode));

464    memset (allocatable_regs_of_mode, 0, sizeof (allocatable_regs_of_mode));

465    for (m = 0; m < (unsigned int) MAX_MACHINE_MODE; m++)

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

467        if ((unsigned) CLASS_MAX_NREGS (i, m) <= reg_class_size[i])

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

469           if (!fixed_regs [j] && TEST_HARD_REG_BIT (reg_class_contents[i], j)

470              && HARD_REGNO_MODE_OK (j, m))

471          {

472            contains_reg_of_mode [i][m] = 1;

473            allocatable_regs_of_mode [m] = 1;

474            break;

475          }

 

Besides, for arrays fixed_regs, call_used_regs, call_fixed_regs, there are bits version objects - fixed_reg_set, call_used_reg_set, call_fixed_reg_set. They are the data the compiler will be used from now on instead as more compact. Also, the information about the availability of machine mode for every register class is very useful too. At line 464, allocatable_regs_of_mode indicates whether specified register can be used for specified mode regardless register class.

 

你可能感兴趣的:(Studying note of GCC-3.4.6 source (43))