mozilla-bmo1756347.patch
branchfirefox98
changeset 1172 7bdeb580be51
equal deleted inserted replaced
1171:130d464159be 1172:7bdeb580be51
       
     1 # HG changeset patch
       
     2 # User Wolfgang Rosenauer <wr@rosenauer.org>
       
     3 # Parent  f805a250257be9c3ea570b34557150450e16dfec
       
     4 
       
     5 diff --git a/js/src/jit/GenerateAtomicOperations.py b/js/src/jit/GenerateAtomicOperations.py
       
     6 --- a/js/src/jit/GenerateAtomicOperations.py
       
     7 +++ b/js/src/jit/GenerateAtomicOperations.py
       
     8 @@ -5,40 +5,41 @@
       
     9  # This script generates jit/AtomicOperationsGenerated.h
       
    10  #
       
    11  # See the big comment in jit/AtomicOperations.h for an explanation.
       
    12  
       
    13  import buildconfig
       
    14  
       
    15  is_64bit = "JS_64BIT" in buildconfig.defines
       
    16  cpu_arch = buildconfig.substs["CPU_ARCH"]
       
    17 +is_gcc = buildconfig.substs["CC_TYPE"] == "gcc"
       
    18  
       
    19  
       
    20  def fmt_insn(s):
       
    21      return '"' + s + '\\n\\t"\n'
       
    22  
       
    23  
       
    24  def gen_seqcst(fun_name):
       
    25      if cpu_arch in ("x86", "x86_64"):
       
    26          return r"""
       
    27 -            inline void %(fun_name)s() {
       
    28 +            INLINE_ATTR void %(fun_name)s() {
       
    29                  asm volatile ("mfence\n\t" ::: "memory");
       
    30              }""" % {
       
    31              "fun_name": fun_name,
       
    32          }
       
    33      if cpu_arch == "aarch64":
       
    34          return r"""
       
    35 -            inline void %(fun_name)s() {
       
    36 +            INLINE_ATTR void %(fun_name)s() {
       
    37                  asm volatile ("dmb ish\n\t" ::: "memory");
       
    38              }""" % {
       
    39              "fun_name": fun_name,
       
    40          }
       
    41      if cpu_arch == "arm":
       
    42          return r"""
       
    43 -            inline void %(fun_name)s() {
       
    44 +            INLINE_ATTR void %(fun_name)s() {
       
    45                  asm volatile ("dmb sy\n\t" ::: "memory");
       
    46              }""" % {
       
    47              "fun_name": fun_name,
       
    48          }
       
    49      raise Exception("Unexpected arch")
       
    50  
       
    51  
       
    52  def gen_load(fun_name, cpp_type, size, barrier):
       
    53 @@ -58,17 +59,17 @@ def gen_load(fun_name, cpp_type, size, b
       
    54          elif size == 32:
       
    55              insns += fmt_insn("movl (%[arg]), %[res]")
       
    56          else:
       
    57              assert size == 64
       
    58              insns += fmt_insn("movq (%[arg]), %[res]")
       
    59          if barrier:
       
    60              insns += fmt_insn("mfence")
       
    61          return """
       
    62 -            inline %(cpp_type)s %(fun_name)s(const %(cpp_type)s* arg) {
       
    63 +            INLINE_ATTR %(cpp_type)s %(fun_name)s(const %(cpp_type)s* arg) {
       
    64                  %(cpp_type)s res;
       
    65                  asm volatile (%(insns)s
       
    66                      : [res] "=r" (res)
       
    67                      : [arg] "r" (arg)
       
    68                      : "memory");
       
    69                  return res;
       
    70              }""" % {
       
    71              "cpp_type": cpp_type,
       
    72 @@ -86,17 +87,17 @@ def gen_load(fun_name, cpp_type, size, b
       
    73          elif size == 32:
       
    74              insns += fmt_insn("ldr %w[res], [%x[arg]]")
       
    75          else:
       
    76              assert size == 64
       
    77              insns += fmt_insn("ldr %x[res], [%x[arg]]")
       
    78          if barrier:
       
    79              insns += fmt_insn("dmb ish")
       
    80          return """
       
    81 -            inline %(cpp_type)s %(fun_name)s(const %(cpp_type)s* arg) {
       
    82 +            INLINE_ATTR %(cpp_type)s %(fun_name)s(const %(cpp_type)s* arg) {
       
    83                  %(cpp_type)s res;
       
    84                  asm volatile (%(insns)s
       
    85                      : [res] "=r" (res)
       
    86                      : [arg] "r" (arg)
       
    87                      : "memory");
       
    88                  return res;
       
    89              }""" % {
       
    90              "cpp_type": cpp_type,
       
    91 @@ -112,17 +113,17 @@ def gen_load(fun_name, cpp_type, size, b
       
    92          elif size == 16:
       
    93              insns += fmt_insn("ldrh %[res], [%[arg]]")
       
    94          else:
       
    95              assert size == 32
       
    96              insns += fmt_insn("ldr %[res], [%[arg]]")
       
    97          if barrier:
       
    98              insns += fmt_insn("dmb sy")
       
    99          return """
       
   100 -            inline %(cpp_type)s %(fun_name)s(const %(cpp_type)s* arg) {
       
   101 +            INLINE_ATTR %(cpp_type)s %(fun_name)s(const %(cpp_type)s* arg) {
       
   102                  %(cpp_type)s res;
       
   103                  asm volatile (%(insns)s
       
   104                      : [res] "=r" (res)
       
   105                      : [arg] "r" (arg)
       
   106                      : "memory");
       
   107                  return res;
       
   108              }""" % {
       
   109              "cpp_type": cpp_type,
       
   110 @@ -149,17 +150,17 @@ def gen_store(fun_name, cpp_type, size, 
       
   111          elif size == 32:
       
   112              insns += fmt_insn("movl %[val], (%[addr])")
       
   113          else:
       
   114              assert size == 64
       
   115              insns += fmt_insn("movq %[val], (%[addr])")
       
   116          if barrier:
       
   117              insns += fmt_insn("mfence")
       
   118          return """
       
   119 -            inline void %(fun_name)s(%(cpp_type)s* addr, %(cpp_type)s val) {
       
   120 +            INLINE_ATTR void %(fun_name)s(%(cpp_type)s* addr, %(cpp_type)s val) {
       
   121                  asm volatile (%(insns)s
       
   122                      :
       
   123                      : [addr] "r" (addr), [val] "r"(val)
       
   124                      : "memory");
       
   125              }""" % {
       
   126              "cpp_type": cpp_type,
       
   127              "fun_name": fun_name,
       
   128              "insns": insns,
       
   129 @@ -175,17 +176,17 @@ def gen_store(fun_name, cpp_type, size, 
       
   130          elif size == 32:
       
   131              insns += fmt_insn("str %w[val], [%x[addr]]")
       
   132          else:
       
   133              assert size == 64
       
   134              insns += fmt_insn("str %x[val], [%x[addr]]")
       
   135          if barrier:
       
   136              insns += fmt_insn("dmb ish")
       
   137          return """
       
   138 -            inline void %(fun_name)s(%(cpp_type)s* addr, %(cpp_type)s val) {
       
   139 +            INLINE_ATTR void %(fun_name)s(%(cpp_type)s* addr, %(cpp_type)s val) {
       
   140                  asm volatile (%(insns)s
       
   141                      :
       
   142                      : [addr] "r" (addr), [val] "r"(val)
       
   143                      : "memory");
       
   144              }""" % {
       
   145              "cpp_type": cpp_type,
       
   146              "fun_name": fun_name,
       
   147              "insns": insns,
       
   148 @@ -199,17 +200,17 @@ def gen_store(fun_name, cpp_type, size, 
       
   149          elif size == 16:
       
   150              insns += fmt_insn("strh %[val], [%[addr]]")
       
   151          else:
       
   152              assert size == 32
       
   153              insns += fmt_insn("str %[val], [%[addr]]")
       
   154          if barrier:
       
   155              insns += fmt_insn("dmb sy")
       
   156          return """
       
   157 -            inline void %(fun_name)s(%(cpp_type)s* addr, %(cpp_type)s val) {
       
   158 +            INLINE_ATTR void %(fun_name)s(%(cpp_type)s* addr, %(cpp_type)s val) {
       
   159                  asm volatile (%(insns)s
       
   160                      :
       
   161                      : [addr] "r" (addr), [val] "r"(val)
       
   162                      : "memory");
       
   163              }""" % {
       
   164              "cpp_type": cpp_type,
       
   165              "fun_name": fun_name,
       
   166              "insns": insns,
       
   167 @@ -230,17 +231,17 @@ def gen_exchange(fun_name, cpp_type, siz
       
   168          elif size == 16:
       
   169              insns += fmt_insn("xchgw %[val], (%[addr])")
       
   170          elif size == 32:
       
   171              insns += fmt_insn("xchgl %[val], (%[addr])")
       
   172          else:
       
   173              assert size == 64
       
   174              insns += fmt_insn("xchgq %[val], (%[addr])")
       
   175          return """
       
   176 -            inline %(cpp_type)s %(fun_name)s(%(cpp_type)s* addr, %(cpp_type)s val) {
       
   177 +            INLINE_ATTR %(cpp_type)s %(fun_name)s(%(cpp_type)s* addr, %(cpp_type)s val) {
       
   178                  asm volatile (%(insns)s
       
   179                      : [val] "+r" (val)
       
   180                      : [addr] "r" (addr)
       
   181                      : "memory");
       
   182                  return val;
       
   183              }""" % {
       
   184              "cpp_type": cpp_type,
       
   185              "fun_name": fun_name,
       
   186 @@ -261,17 +262,17 @@ def gen_exchange(fun_name, cpp_type, siz
       
   187              insns += fmt_insn("stxr %w[scratch], %w[val], [%x[addr]]")
       
   188          else:
       
   189              assert size == 64
       
   190              insns += fmt_insn("ldxr %x[res], [%x[addr]]")
       
   191              insns += fmt_insn("stxr %w[scratch], %x[val], [%x[addr]]")
       
   192          insns += fmt_insn("cbnz %w[scratch], 0b")
       
   193          insns += fmt_insn("dmb ish")
       
   194          return """
       
   195 -            inline %(cpp_type)s %(fun_name)s(%(cpp_type)s* addr, %(cpp_type)s val) {
       
   196 +            INLINE_ATTR %(cpp_type)s %(fun_name)s(%(cpp_type)s* addr, %(cpp_type)s val) {
       
   197                  %(cpp_type)s res;
       
   198                  uint32_t scratch;
       
   199                  asm volatile (%(insns)s
       
   200                      : [res] "=&r"(res), [scratch] "=&r"(scratch)
       
   201                      : [addr] "r" (addr), [val] "r"(val)
       
   202                      : "memory", "cc");
       
   203                  return res;
       
   204              }""" % {
       
   205 @@ -292,17 +293,17 @@ def gen_exchange(fun_name, cpp_type, siz
       
   206          else:
       
   207              assert size == 32
       
   208              insns += fmt_insn("ldrex %[res], [%[addr]]")
       
   209              insns += fmt_insn("strex %[scratch], %[val], [%[addr]]")
       
   210          insns += fmt_insn("cmp %[scratch], #1")
       
   211          insns += fmt_insn("beq 0b")
       
   212          insns += fmt_insn("dmb sy")
       
   213          return """
       
   214 -            inline %(cpp_type)s %(fun_name)s(%(cpp_type)s* addr, %(cpp_type)s val) {
       
   215 +            INLINE_ATTR %(cpp_type)s %(fun_name)s(%(cpp_type)s* addr, %(cpp_type)s val) {
       
   216                  %(cpp_type)s res;
       
   217                  uint32_t scratch;
       
   218                  asm volatile (%(insns)s
       
   219                      : [res] "=&r"(res), [scratch] "=&r"(scratch)
       
   220                      : [addr] "r" (addr), [val] "r"(val)
       
   221                      : "memory", "cc");
       
   222                  return res;
       
   223              }""" % {
       
   224 @@ -316,33 +317,33 @@ def gen_exchange(fun_name, cpp_type, siz
       
   225  def gen_cmpxchg(fun_name, cpp_type, size):
       
   226      # NOTE: the assembly code must match the generated code in:
       
   227      # - MacroAssembler::compareExchange
       
   228      # - MacroAssembler::compareExchange64
       
   229      if cpu_arch == "x86" and size == 64:
       
   230          # Use a +A constraint to load `oldval` into EDX:EAX as input/output.
       
   231          # `newval` is loaded into ECX:EBX.
       
   232          return r"""
       
   233 -            inline %(cpp_type)s %(fun_name)s(%(cpp_type)s* addr,
       
   234 +            INLINE_ATTR %(cpp_type)s %(fun_name)s(%(cpp_type)s* addr,
       
   235                                               %(cpp_type)s oldval,
       
   236                                               %(cpp_type)s newval) {
       
   237                  asm volatile ("lock; cmpxchg8b (%%[addr])\n\t"
       
   238                  : "+A" (oldval)
       
   239                  : [addr] "r" (addr),
       
   240                    "b" (uint32_t(newval & 0xffff'ffff)),
       
   241                    "c" (uint32_t(newval >> 32))
       
   242                  : "memory", "cc");
       
   243                  return oldval;
       
   244              }""" % {
       
   245              "cpp_type": cpp_type,
       
   246              "fun_name": fun_name,
       
   247          }
       
   248      if cpu_arch == "arm" and size == 64:
       
   249          return r"""
       
   250 -            inline %(cpp_type)s %(fun_name)s(%(cpp_type)s* addr,
       
   251 +            INLINE_ATTR %(cpp_type)s %(fun_name)s(%(cpp_type)s* addr,
       
   252                                               %(cpp_type)s oldval,
       
   253                                               %(cpp_type)s newval) {
       
   254                  uint32_t oldval0 = oldval & 0xffff'ffff;
       
   255                  uint32_t oldval1 = oldval >> 32;
       
   256                  uint32_t newval0 = newval & 0xffff'ffff;
       
   257                  uint32_t newval1 = newval >> 32;
       
   258                  asm volatile (
       
   259                      "dmb sy\n\t"
       
   260 @@ -375,17 +376,17 @@ def gen_cmpxchg(fun_name, cpp_type, size
       
   261          elif size == 16:
       
   262              insns += fmt_insn("lock; cmpxchgw %[newval], (%[addr])")
       
   263          elif size == 32:
       
   264              insns += fmt_insn("lock; cmpxchgl %[newval], (%[addr])")
       
   265          else:
       
   266              assert size == 64
       
   267              insns += fmt_insn("lock; cmpxchgq %[newval], (%[addr])")
       
   268          return """
       
   269 -            inline %(cpp_type)s %(fun_name)s(%(cpp_type)s* addr,
       
   270 +            INLINE_ATTR %(cpp_type)s %(fun_name)s(%(cpp_type)s* addr,
       
   271                                               %(cpp_type)s oldval,
       
   272                                               %(cpp_type)s newval) {
       
   273                  asm volatile (%(insns)s
       
   274                      : [oldval] "+a" (oldval)
       
   275                      : [addr] "r" (addr), [newval] "r" (newval)
       
   276                      : "memory", "cc");
       
   277                  return oldval;
       
   278              }""" % {
       
   279 @@ -420,17 +421,17 @@ def gen_cmpxchg(fun_name, cpp_type, size
       
   280              insns += fmt_insn("mov %x[scratch], %x[oldval]")
       
   281              insns += fmt_insn("ldxr %x[res], [%x[addr]]")
       
   282              insns += fmt_insn("cmp %x[res], %x[scratch]")
       
   283              insns += fmt_insn("b.ne 1f")
       
   284              insns += fmt_insn("stxr %w[scratch], %x[newval], [%x[addr]]")
       
   285          insns += fmt_insn("cbnz %w[scratch], 0b")
       
   286          insns += fmt_insn("1: dmb ish")
       
   287          return """
       
   288 -            inline %(cpp_type)s %(fun_name)s(%(cpp_type)s* addr,
       
   289 +            INLINE_ATTR %(cpp_type)s %(fun_name)s(%(cpp_type)s* addr,
       
   290                                               %(cpp_type)s oldval,
       
   291                                               %(cpp_type)s newval) {
       
   292                  %(cpp_type)s res, scratch;
       
   293                  asm volatile (%(insns)s
       
   294                      : [res] "=&r" (res), [scratch] "=&r" (scratch)
       
   295                      : [addr] "r" (addr), [oldval] "r"(oldval), [newval] "r" (newval)
       
   296                      : "memory", "cc");
       
   297                  return res;
       
   298 @@ -461,17 +462,17 @@ def gen_cmpxchg(fun_name, cpp_type, size
       
   299              insns += fmt_insn("ldrex %[res], [%[addr]]")
       
   300              insns += fmt_insn("cmp %[res], %[scratch]")
       
   301              insns += fmt_insn("bne 1f")
       
   302              insns += fmt_insn("strex %[scratch], %[newval], [%[addr]]")
       
   303          insns += fmt_insn("cmp %[scratch], #1")
       
   304          insns += fmt_insn("beq 0b")
       
   305          insns += fmt_insn("1: dmb sy")
       
   306          return """
       
   307 -            inline %(cpp_type)s %(fun_name)s(%(cpp_type)s* addr,
       
   308 +            INLINE_ATTR %(cpp_type)s %(fun_name)s(%(cpp_type)s* addr,
       
   309                                               %(cpp_type)s oldval,
       
   310                                               %(cpp_type)s newval) {
       
   311                  %(cpp_type)s res, scratch;
       
   312                  asm volatile (%(insns)s
       
   313                      : [res] "=&r" (res), [scratch] "=&r" (scratch)
       
   314                      : [addr] "r" (addr), [oldval] "r"(oldval), [newval] "r" (newval)
       
   315                      : "memory", "cc");
       
   316                  return res;
       
   317 @@ -496,17 +497,17 @@ def gen_fetchop(fun_name, cpp_type, size
       
   318              elif size == 16:
       
   319                  insns += fmt_insn("lock; xaddw %[val], (%[addr])")
       
   320              elif size == 32:
       
   321                  insns += fmt_insn("lock; xaddl %[val], (%[addr])")
       
   322              else:
       
   323                  assert size == 64
       
   324                  insns += fmt_insn("lock; xaddq %[val], (%[addr])")
       
   325              return """
       
   326 -                inline %(cpp_type)s %(fun_name)s(%(cpp_type)s* addr, %(cpp_type)s val) {
       
   327 +                INLINE_ATTR %(cpp_type)s %(fun_name)s(%(cpp_type)s* addr, %(cpp_type)s val) {
       
   328                      asm volatile (%(insns)s
       
   329                          : [val] "+&r" (val)
       
   330                          : [addr] "r" (addr)
       
   331                          : "memory", "cc");
       
   332                      return val;
       
   333                  }""" % {
       
   334                  "cpp_type": cpp_type,
       
   335                  "fun_name": fun_name,
       
   336 @@ -534,17 +535,17 @@ def gen_fetchop(fun_name, cpp_type, size
       
   337              assert size == 64
       
   338              insns += fmt_insn("movq (%[addr]), %[res]")
       
   339              insns += fmt_insn("0: movq %[res], %[scratch]")
       
   340              insns += fmt_insn("OPq %[val], %[scratch]")
       
   341              insns += fmt_insn("lock; cmpxchgq %[scratch], (%[addr])")
       
   342          insns = insns.replace("OP", op)
       
   343          insns += fmt_insn("jnz 0b")
       
   344          return """
       
   345 -            inline %(cpp_type)s %(fun_name)s(%(cpp_type)s* addr, %(cpp_type)s val) {
       
   346 +            INLINE_ATTR %(cpp_type)s %(fun_name)s(%(cpp_type)s* addr, %(cpp_type)s val) {
       
   347                  %(cpp_type)s res, scratch;
       
   348                  asm volatile (%(insns)s
       
   349                      : [res] "=&a" (res), [scratch] "=&r" (scratch)
       
   350                      : [addr] "r" (addr), [val] "r"(val)
       
   351                      : "memory", "cc");
       
   352                  return res;
       
   353              }""" % {
       
   354              "cpp_type": cpp_type,
       
   355 @@ -576,17 +577,17 @@ def gen_fetchop(fun_name, cpp_type, size
       
   356          if cpu_op == "or":
       
   357              cpu_op = "orr"
       
   358          if cpu_op == "xor":
       
   359              cpu_op = "eor"
       
   360          insns = insns.replace("OP", cpu_op)
       
   361          insns += fmt_insn("cbnz %w[scratch2], 0b")
       
   362          insns += fmt_insn("dmb ish")
       
   363          return """
       
   364 -            inline %(cpp_type)s %(fun_name)s(%(cpp_type)s* addr, %(cpp_type)s val) {
       
   365 +            INLINE_ATTR %(cpp_type)s %(fun_name)s(%(cpp_type)s* addr, %(cpp_type)s val) {
       
   366                  %(cpp_type)s res;
       
   367                  uintptr_t scratch1, scratch2;
       
   368                  asm volatile (%(insns)s
       
   369                      : [res] "=&r" (res), [scratch1] "=&r" (scratch1), [scratch2] "=&r"(scratch2)
       
   370                      : [addr] "r" (addr), [val] "r"(val)
       
   371                      : "memory", "cc");
       
   372                  return res;
       
   373              }""" % {
       
   374 @@ -616,17 +617,17 @@ def gen_fetchop(fun_name, cpp_type, size
       
   375              cpu_op = "orr"
       
   376          if cpu_op == "xor":
       
   377              cpu_op = "eor"
       
   378          insns = insns.replace("OP", cpu_op)
       
   379          insns += fmt_insn("cmp %[scratch2], #1")
       
   380          insns += fmt_insn("beq 0b")
       
   381          insns += fmt_insn("dmb sy")
       
   382          return """
       
   383 -            inline %(cpp_type)s %(fun_name)s(%(cpp_type)s* addr, %(cpp_type)s val) {
       
   384 +            INLINE_ATTR %(cpp_type)s %(fun_name)s(%(cpp_type)s* addr, %(cpp_type)s val) {
       
   385                  %(cpp_type)s res;
       
   386                  uintptr_t scratch1, scratch2;
       
   387                  asm volatile (%(insns)s
       
   388                      : [res] "=&r" (res), [scratch1] "=&r" (scratch1), [scratch2] "=&r"(scratch2)
       
   389                      : [addr] "r" (addr), [val] "r"(val)
       
   390                      : "memory", "cc");
       
   391                  return res;
       
   392              }""" % {
       
   393 @@ -660,33 +661,33 @@ def gen_copy(fun_name, cpp_type, size, u
       
   394                  insns += fmt_insn("ldrb %w[scratch], [%x[src], OFFSET]")
       
   395                  insns += fmt_insn("strb %w[scratch], [%x[dst], OFFSET]")
       
   396              else:
       
   397                  assert size == 8
       
   398                  insns += fmt_insn("ldr %x[scratch], [%x[src], OFFSET]")
       
   399                  insns += fmt_insn("str %x[scratch], [%x[dst], OFFSET]")
       
   400          elif cpu_arch == "arm":
       
   401              if size == 1:
       
   402 -                insns += fmt_insn("ldrb %[scratch], [%[src], OFFSET]")
       
   403 -                insns += fmt_insn("strb %[scratch], [%[dst], OFFSET]")
       
   404 +                insns += fmt_insn("ldrb %[scratch], [%[src], #OFFSET]")
       
   405 +                insns += fmt_insn("strb %[scratch], [%[dst], #OFFSET]")
       
   406              else:
       
   407                  assert size == 4
       
   408 -                insns += fmt_insn("ldr %[scratch], [%[src], OFFSET]")
       
   409 -                insns += fmt_insn("str %[scratch], [%[dst], OFFSET]")
       
   410 +                insns += fmt_insn("ldr %[scratch], [%[src], #OFFSET]")
       
   411 +                insns += fmt_insn("str %[scratch], [%[dst], #OFFSET]")
       
   412          else:
       
   413              raise Exception("Unexpected arch")
       
   414          insns = insns.replace("OFFSET", str(offset * size))
       
   415  
       
   416          if direction == "down":
       
   417              offset += 1
       
   418          else:
       
   419              offset -= 1
       
   420  
       
   421      return """
       
   422 -        inline void %(fun_name)s(uint8_t* dst, const uint8_t* src) {
       
   423 +        INLINE_ATTR void %(fun_name)s(uint8_t* dst, const uint8_t* src) {
       
   424              %(cpp_type)s* dst_ = reinterpret_cast<%(cpp_type)s*>(dst);
       
   425              const %(cpp_type)s* src_ = reinterpret_cast<const %(cpp_type)s*>(src);
       
   426              %(cpp_type)s scratch;
       
   427              asm volatile (%(insns)s
       
   428                  : [scratch] "=&r" (scratch)
       
   429                  : [dst] "r" (dst_), [src] "r"(src_)
       
   430                  : "memory");
       
   431          }""" % {
       
   432 @@ -848,14 +849,21 @@ def generate_atomics_header(c_out):
       
   433              "constexpr size_t JS_GENERATED_ATOMICS_BLOCKSIZE = "
       
   434              + str(blocksize)
       
   435              + ";\n"
       
   436          )
       
   437          contents += (
       
   438              "constexpr size_t JS_GENERATED_ATOMICS_WORDSIZE = " + str(wordsize) + ";\n"
       
   439          )
       
   440  
       
   441 +        # Work around a GCC issue on 32-bit x86 by adding MOZ_NEVER_INLINE.
       
   442 +        # See bug 1756347.
       
   443 +        if is_gcc and cpu_arch == "x86":
       
   444 +            contents = contents.replace("INLINE_ATTR", "MOZ_NEVER_INLINE inline")
       
   445 +        else:
       
   446 +            contents = contents.replace("INLINE_ATTR", "inline")
       
   447 +
       
   448      c_out.write(
       
   449          HEADER_TEMPLATE
       
   450          % {
       
   451              "contents": contents,
       
   452          }
       
   453      )