1#!/usr/bin/python
2# Copyright (c) 2012 The Native Client Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6import driver_tools
7from driver_env import env
8from driver_log import Log
9import sys
10
11EXTRA_ENV = {
12  'INPUTS'      : '',
13  'OUTPUT'      : '',
14
15  'MC_FLAGS'       : '-assemble -filetype=obj ${MC_FLAGS_%ARCH%}',
16  'MC_FLAGS_ARM'   : ('-arch=arm -triple=armv7a-nacl -mcpu=cortex-a9 ' +
17                      '-mattr=+neon'),
18  'MC_FLAGS_X8632' : '-arch=x86 -triple=i686-nacl',
19  'MC_FLAGS_X8664' : '-arch=x86-64 -triple=x86_64-nacl',
20  'MC_FLAGS_MIPS32': '-arch=mipsel -triple=mipsel-nacl',
21  'MC_FLAGS_ARM_NONSFI': ('-arch=arm -triple=armv7a -mcpu=cortex-a9 '
22                          '-mattr=+neon'),
23  'MC_FLAGS_X8632_NONSFI': '-arch=x86 -triple=i686',
24
25  'RUN_LLVM_AS'    : '${LLVM_AS} ${input} -o ${output}',
26  'RUN_LLVM_MC'    : '${LLVM_MC} ${MC_FLAGS} ${input} -o ${output}',
27}
28
29VERSION_STR = """Portable Native Client assembler
30Compatibility:
31GNU assembler version 2.21.51 (pnacl-pc-nacl) using BFD version (GNU Binutils) 2.21.51.20110525
32Low Level Virtual Machine (http://llvm.org/)
33"""
34
35def DumpVersionDebug():
36  sys.stderr.write(VERSION_STR)
37
38def DumpVersionAndExit():
39  sys.stdout.write(VERSION_STR)
40  driver_tools.DriverExit(0)
41
42ASPatterns = [
43  ( '-o(.+)',          "env.set('OUTPUT', pathtools.normalize($0))"),
44  ( ('-o', '(.+)'),    "env.set('OUTPUT', pathtools.normalize($0))"),
45
46  ( '-v',              DumpVersionDebug),
47  ( '--version',       DumpVersionAndExit),
48
49  # Ignore these assembler flags
50  ( '(-Qy)',                  ""),
51  ( ('(--traditional-format)', '.*'), ""),
52  ( '(-gstabs)',              ""),
53  ( '(--gstabs)',             ""),
54  ( '(-gdwarf2)',             ""),
55  ( '(--gdwarf2)',            ""),
56  ( '(--fatal-warnings)',     ""),
57  ( '(-meabi=.*)',            ""),
58  ( '(-mfpu=.*)',             ""),
59  ( '(-march=.*)',            ""),
60
61  ( '(-.+)',  driver_tools.UnrecognizedOption),
62
63  # Unmatched parameters should be treated as
64  # assembly inputs by the "as" incarnation.
65  ( '(-)',   "env.append('INPUTS', $0)"),
66  ( '(.*)',  "env.append('INPUTS', pathtools.normalize($0))"),
67]
68
69def main(argv):
70  env.update(EXTRA_ENV)
71  driver_tools.ParseArgs(argv, ASPatterns)
72  arch = driver_tools.GetArch()
73
74  inputs = env.get('INPUTS')
75  output = env.getone('OUTPUT')
76
77  for path in inputs + [output]:
78    driver_tools.CheckPathLength(path)
79
80  num_inputs = len(inputs)
81  if num_inputs > 1:
82    Log.Fatal('Expecting exactly one input file')
83  elif num_inputs == 1:
84    the_input = inputs[0]
85  else:
86    # stdin
87    the_input = '-'
88
89
90  if arch:
91    output_type = 'o'
92  else:
93    output_type = 'po'
94
95  if output == '':
96    output = 'a.out'
97
98  env.push()
99  env.set('input', the_input)
100  env.set('output', output)
101
102  if output_type == 'po':
103    # .ll to .po
104    driver_tools.Run("${RUN_LLVM_AS}")
105  else:
106    # .s to .o
107    driver_tools.Run("${RUN_LLVM_MC}")
108  env.pop()
109  # only reached in case of no errors
110  return 0
111
112def get_help(argv):
113  return """
114LLVM Assembler for PNaCl
115Transform LLVM assembly (.ll) to LLVM bitcode.
116
117Usage: pnacl-as [options] <input .ll file> -o <output.po>
118
119OPTIONS:
120  -o <file>        Output to file
121  --version        Display version information
122  -help | -h       Output this help.
123"""
124