1
/****************************************************************************
3
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
4
** Contact: http://www.qt-project.org/legal
6
** This file is part of the QtQml module of the Qt Toolkit.
8
** $QT_BEGIN_LICENSE:LGPL$
9
** Commercial License Usage
10
** Licensees holding valid commercial Qt licenses may use this file in
11
** accordance with the commercial license agreement provided with the
12
** Software or, alternatively, in accordance with the terms contained in
13
** a written agreement between you and Digia. For licensing terms and
14
** conditions see http://qt.digia.com/licensing. For further information
15
** use the contact form at http://qt.digia.com/contact-us.
17
** GNU Lesser General Public License Usage
18
** Alternatively, this file may be used under the terms of the GNU Lesser
19
** General Public License version 2.1 as published by the Free Software
20
** Foundation and appearing in the file LICENSE.LGPL included in the
21
** packaging of this file. Please review the following information to
22
** ensure the GNU Lesser General Public License version 2.1 requirements
23
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25
** In addition, as a special exception, Digia gives you certain additional
26
** rights. These rights are described in the Digia Qt LGPL Exception
27
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29
** GNU General Public License Usage
30
** Alternatively, this file may be used under the terms of the GNU
31
** General Public License version 3.0 as published by the Free Software
32
** Foundation and appearing in the file LICENSE.GPL included in the
33
** packaging of this file. Please review the following information to
34
** ensure the GNU General Public License version 3.0 requirements will be
35
** met: http://www.gnu.org/copyleft/gpl.html.
40
****************************************************************************/
41
#include <qv4unop_p.h>
42
#include <qv4assembler_p.h>
49
#define stringIfyx(s) #s
50
#define stringIfy(s) stringIfyx(s)
51
#define setOp(operation) \
52
do { call = operation; name = stringIfy(operation); } while (0)
54
void Unop::generate(IR::Temp *source, IR::Temp *target)
56
Runtime::UnaryOperation call = 0;
60
generateNot(source, target);
63
generateUMinus(source, target);
65
case IR::OpUPlus: setOp(Runtime::uPlus); break;
67
generateCompl(source, target);
69
case IR::OpIncrement: setOp(Runtime::increment); break;
70
case IR::OpDecrement: setOp(Runtime::decrement); break;
76
as->generateFunctionCallImp(target, name, call, Assembler::PointerToValue(source));
80
void Unop::generateUMinus(IR::Temp *source, IR::Temp *target)
82
if (source->type == IR::SInt32Type) {
83
Assembler::RegisterID tReg = Assembler::ScratchRegister;
84
if (target->kind == IR::Temp::PhysicalRegister)
85
tReg = (Assembler::RegisterID) target->index;
86
Assembler::RegisterID sReg = as->toInt32Register(source, tReg);
89
if (target->kind != IR::Temp::PhysicalRegister)
90
as->storeInt32(tReg, target);
94
as->generateFunctionCallImp(target, "Runtime::uMinus", Runtime::uMinus, Assembler::PointerToValue(source));
97
void Unop::generateNot(IR::Temp *source, IR::Temp *target)
99
if (source->type == IR::BoolType) {
100
Assembler::RegisterID tReg = Assembler::ScratchRegister;
101
if (target->kind == IR::Temp::PhysicalRegister)
102
tReg = (Assembler::RegisterID) target->index;
103
as->xor32(Assembler::TrustedImm32(0x1), as->toInt32Register(source, tReg), tReg);
104
if (target->kind != IR::Temp::PhysicalRegister)
105
as->storeBool(tReg, target);
107
} else if (source->type == IR::SInt32Type) {
108
Assembler::RegisterID tReg = Assembler::ScratchRegister;
109
if (target->kind == IR::Temp::PhysicalRegister)
110
tReg = (Assembler::RegisterID) target->index;
111
as->compare32(Assembler::Equal,
112
as->toInt32Register(source, Assembler::ScratchRegister), Assembler::TrustedImm32(0),
114
if (target->kind != IR::Temp::PhysicalRegister)
115
as->storeBool(tReg, target);
117
} else if (source->type == IR::DoubleType) {
120
// ## generic implementation testing for int/bool
122
as->generateFunctionCallImp(target, "Runtime::uNot", Runtime::uNot, Assembler::PointerToValue(source));
125
void Unop::generateCompl(IR::Temp *source, IR::Temp *target)
127
if (source->type == IR::SInt32Type) {
128
Assembler::RegisterID tReg = Assembler::ScratchRegister;
129
if (target->kind == IR::Temp::PhysicalRegister)
130
tReg = (Assembler::RegisterID) target->index;
131
as->xor32(Assembler::TrustedImm32(0xffffffff), as->toInt32Register(source, tReg), tReg);
132
if (target->kind != IR::Temp::PhysicalRegister)
133
as->storeInt32(tReg, target);
136
as->generateFunctionCallImp(target, "Runtime::complement", Runtime::complement, Assembler::PointerToValue(source));