blob: 7e4baf84e77b31f71a35b51957ac85f98d3a6409 [file] [log] [blame]
Daniel Dunbarfc6877a2009-06-29 20:40:36 +00001//===- AsmExpr.cpp - Assembly file expressions ----------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "AsmExpr.h"
11#include "llvm/MC/MCContext.h"
12#include "llvm/MC/MCValue.h"
13using namespace llvm;
14
15AsmExpr::~AsmExpr() {
16}
17
18bool AsmExpr::EvaluateAsAbsolute(MCContext &Ctx, int64_t &Res) const {
19 switch (getKind()) {
20 default:
21 assert(0 && "Invalid assembly expression kind!");
22
23 case Constant:
24 Res = cast<AsmConstantExpr>(this)->getValue();
25 return true;
26
27 case SymbolRef: {
28 MCSymbol *Sym = cast<AsmSymbolRefExpr>(this)->getSymbol();
29 const MCValue *Value = Ctx.GetSymbolValue(Sym);
30
31 // FIXME: Return more information about the failure.
32 if (!Value || !Value->isConstant())
33 return false;
34
35 Res = Value->getConstant();
36 return true;
37 }
38
39 case Unary: {
40 const AsmUnaryExpr *AUE = cast<AsmUnaryExpr>(this);
41 int64_t Value;
42
43 if (!AUE->getSubExpr()->EvaluateAsAbsolute(Ctx, Value))
44 return false;
45
46 switch (AUE->getOpcode()) {
47 case AsmUnaryExpr::LNot: Res = !Value; break;
48 case AsmUnaryExpr::Minus: Res = -Value; break;
49 case AsmUnaryExpr::Not: Res = ~Value; break;
50 case AsmUnaryExpr::Plus: Res = +Value; break;
51 }
52
53 return true;
54 }
55
56 case Binary: {
57 const AsmBinaryExpr *ABE = cast<AsmBinaryExpr>(this);
58 int64_t LHS, RHS;
59
60 if (!ABE->getLHS()->EvaluateAsAbsolute(Ctx, LHS) ||
61 !ABE->getRHS()->EvaluateAsAbsolute(Ctx, RHS))
62 return false;
63
64 // FIXME: We need target hooks for the evaluation. It may be limited in
65 // width, and gas defines the result of comparisons differently from Apple
66 // as (the result is sign extended).
67 switch (ABE->getOpcode()) {
68 case AsmBinaryExpr::Add: Res = LHS + RHS; break;
69 case AsmBinaryExpr::And: Res = LHS & RHS; break;
70 case AsmBinaryExpr::Div: Res = LHS / RHS; break;
71 case AsmBinaryExpr::EQ: Res = LHS == RHS; break;
72 case AsmBinaryExpr::GT: Res = LHS > RHS; break;
73 case AsmBinaryExpr::GTE: Res = LHS >= RHS; break;
74 case AsmBinaryExpr::LAnd: Res = LHS && RHS; break;
75 case AsmBinaryExpr::LOr: Res = LHS || RHS; break;
76 case AsmBinaryExpr::LT: Res = LHS < RHS; break;
77 case AsmBinaryExpr::LTE: Res = LHS <= RHS; break;
78 case AsmBinaryExpr::Mod: Res = LHS % RHS; break;
79 case AsmBinaryExpr::Mul: Res = LHS * RHS; break;
80 case AsmBinaryExpr::NE: Res = LHS != RHS; break;
81 case AsmBinaryExpr::Or: Res = LHS | RHS; break;
82 case AsmBinaryExpr::Shl: Res = LHS << RHS; break;
83 case AsmBinaryExpr::Shr: Res = LHS >> RHS; break;
84 case AsmBinaryExpr::Sub: Res = LHS - RHS; break;
85 case AsmBinaryExpr::Xor: Res = LHS ^ RHS; break;
86 }
87
88 return true;
89 }
90 }
91}
92